我一直在开发一些DLL实用程序项目,以避免在其他项目中重复编写代码,并用于我尚未尝试的功能、算法和测试。其中一个项目是用C++/CLI语言编写的,这是我还在学习的语言,所以这个问题可能听起来很愚蠢。由于我有用C++/CLI、F#和C#编写的库项目,我使用一个C#控制台应用程序来测试它们。但对于C++/CLI项目,它就无法正常工作,所以我创建了一个C++/CLI控制台测试项目,但它从未正常工作过。当我更改了原始DLL C++的名称时,引用没有更新。最终我发现了问题,我更改了.vcxproj文件,使using指令成为可能,可以用于一个方法,但不能用于模板类
我还从本网站上的帖子中发现,我必须在项目内部使用想要在外部使用的内容,否则这些内容将不会被包含在元数据中。因此,我在一个静态实用程序中增加了一个无用的静态方法来实现这一目的:
Apont<typename T>
,它是一种内部指针,但与.NET类型System::IntPtr
不同,它使用类型值T*
而不是void*
。我还从本网站上的帖子中发现,我必须在项目内部使用想要在外部使用的内容,否则这些内容将不会被包含在元数据中。因此,我在一个静态实用程序中增加了一个无用的静态方法来实现这一目的:
static void Funcionalidades()
{
int i = 10;
Apont<int> a2 = Apont<int>(i); // stack
Apont<int> ^a3 = gcnew Apont<int>(i); // heap CLR
}
然而,它并没有起作用。以下是我在C++/CLI测试项目中的主要方法:
int main(array<System::String ^> ^args)
{
int y(10);
Apont<int> a = Apont<int>(y);
Console::ReadKey();
return 0;
}
以下是错误信息(我知道它可以编译并在智能感知中显示错误,但我仍然会展示它们):
error C2065: 'Apont' : undeclared identifier
error C2062: type 'int' unexpected
IntelliSense: identifier "Apont" is undefined
IntelliSense: type name is not allowed
IntelliSense: expected an expression
为什么会出现这些错误?我该如何纠正它们?
非常感谢任何回答或者回复。
编辑(澄清):
- 这些错误并没有发生在DLL项目中的
Funcionalidades
方法上,而是发生在测试项目之外的主方法上。 - 我正在头文件中编写所有内容;我的意思是,并不是每个头文件都有相应的.cpp文件,尽管所有头文件都至少被一个.cpp文件包含。
- 更多关于
Apont
的信息:Apont
是一个模板(因为T*被用在里面,“对通用类型参数进行间接引用是不允许的”)。Apont
有一个拷贝构造函数,所以Apont<int> a = Apont<int>(someInt)
应该可以工作;Apont<int> a(someInt)
无法工作;Apont
是某种内部指针;我没有发布整个代码,因为它不相关,我必须翻译变量名称,而且可能有一些我可以轻松修复的错误,但那只会分散你的注意力。
第N次编辑(其中“n”是我不知道的数字):
你一直在抱怨的Apont
代码:
template<typename T> public ref class Apont sealed : public IDisposable
{
bool eliminado;
T *pointer;
/*void Dispose(bool tudo)
{
if (!eliminado)
{
if (tudo)
{
~Apont();
}
else
{
!Apont();
}
}
}*/
!Apont() // finalizador: limpa os recursos "unmanaged"
{
delete pointer;
pointer = nullptr;
eliminado = true;
}
public:
Apont(T &valor)
{
pointer = &valor;
eliminado = false;
ErroSeNulo = false;
ErroSeEliminado = true;
}
Apont(T &valor, bool erroSeEliminado, bool erroSeNulo)
{
pointer = &valor;
eliminado = false;
ErroSeEliminado = erroSeEliminado;
ErroSeNulo = erroSeNulo;
}
Apont(Apont<T> %outroApont)
{
this->pointer = &outroApont
}
property bool ErroSeEliminado;
property bool ErroSeNulo;
property T Valor
{
T get()
{
if (pointer != nullptr)
return *pointer;
else if (eliminado && ErroSeEliminado)
throw gcnew ObjectDisposedException("O objeto já foi pelo menos parcialmente eliminadao.");
else if (ErroSeNulo)
throw gcnew NullReferenceException();
else
return 0;
}
}
/*
Apont operator ~(/*T valor* /)
{
// este operador tem de ser declarado fora desta classe
}*/
T operator !(/*Apont apont*/)
{
return Valor;
}
void operator =(Apont<T> outroApont)
{
pointer = outroApont;
ErroSeEliminado = outroApont.ErroSeEliminado;
ErroSeNulo = outroApont.ErroSeNulo;
}
template<typename U> void operator =(Apont<U> outroApont)
{
pointer = safe_cast<T>(outroApont.pointer);
ErroSeEliminado = safe_cast<T>(outroApont.ErroSeEliminado);
ErroSeNulo = safe_cast<T>(outroApont.ErroSeNulo);
}
/*
void operator =(T *&outroPointer)
{
pointer = outroPointer;
}
template<typename U> void operator =(U *&outroPointer)
{
pointer = safe_cast<T>(outroPointer);
}*/
void operator =(T *outroPointer)
{
pointer = outroPointer;
}
template<typename U> void operator =(U *outroPointer)
{
pointer = safe_cast<T>(outroPointer);
}
~Apont() // destruidor: limpa todos os recursos
{
this->!Apont();
}
// Error C2605: 'Dispose': this method is reserved within a managed class
// O código será gerado automaticamente a partir do finalizador e do destrutor
};
template<typename T> Apont<T> operator ~(T &valor)
{
return gcnew Apont<T>(valor);
}
link /dump /exports mydll.dll
从dll中揭示内部名称。使用我之前提到的链接命令检查您期望存在的值和函数是否实际存在于您的dll中。让我知道您的进展情况,我会尽力帮助您解决这个问题。 - GMasucci属性,链接器,调试,生成调试信息=否
,这样名称就不会被混淆,而且可以正确显示。另外,dumpbin.exe也可以完成类似的工作(VS命令行),或者dependency walker有一个漂亮的GUI来实现相同的功能。我正在研究这个隐藏函数名问题,因为我的一些dll也有同样的问题,但是当我导入dll时,在vs中这些函数是可用的...非常奇怪。 - GMasucciUtilidades.ComNativos
是我查看dll时得到的命名空间,Apont
根本没有暴露出来,但是UtilCMM
是的。也许可以看一下这两个类的区别?(起点可能是:apont是一个密封类,utilscmm是一个静态类) - GMasucci