C#P \调用DLL没有进入C+的入口点+;? 我有一个C++ DLL“Foo.dll”,方法是“PULL()”< /P> < >我可以访问其他C++代码,只需调用:< /p> Foo();
我相信这种方法确实有以下优点:C#P \调用DLL没有进入C+的入口点+;? 我有一个C++ DLL“Foo.dll”,方法是“PULL()”< /P> < >我可以访问其他C++代码,只需调用:< /p> Foo();,c#,pinvoke,dllimport,C#,Pinvoke,Dllimport,我相信这种方法确实有以下优点: __declspec( dllexport ) 因此,通过阅读关于p/Invoke的内容,我认为我应该能够从我的C#代码中简单地调用相同的方法: 为什么不找到它? < P>你应该提供更多关于C++的信息。尝试改用extern“C”\uu declspec(dllexport)。C++输出的名称很奇怪,所以使用外“C”避免了。< P>您应该提供更多关于C++的信息。尝试改用extern“C”\uu declspec(dllexport)。C++输出有奇怪的名字,
__declspec( dllexport )
因此,通过阅读关于p/Invoke的内容,我认为我应该能够从我的C#代码中简单地调用相同的方法:
为什么不找到它? < P>你应该提供更多关于C++的信息。尝试改用
extern“C”\uu declspec(dllexport)
。C++输出的名称很奇怪,所以使用<代码>外“C”<代码>避免了。< P>您应该提供更多关于C++的信息。尝试改用extern“C”\uu declspec(dllexport)
。C++输出有奇怪的名字,所以使用<代码>外“C”<代码>避免了。 如果你没有在你的DLL中声明它“外”“C”,它的名字很可能被“Mulink”。您可以使用Dependency Walker之类的工具查看dll导出的符号。如果您没有在dll中将其声明为extern“C”,则其名称可能已被“损坏”。您可以使用依赖性沃克之类的东西来查看DLL导出的符号。 < P> C++语言支持重载,就像C语言一样。您可以导出函数voidfoo(int)
和函数voidfoo(double)
。显然,这两个函数不能同时导出为“Foo”,DLL的客户端不知道选择哪个函数。事实并非如此
C++编译器通过对函数名的修饰来解决这个问题。添加使Foo(int)不同于Foo(double)的额外字符。通过从列出导出函数名称的Visual Studio命令提示符运行
Dumpbin.exe/exports foo.dll
,可以看到这些修饰的名称。假设您的声明是相关的,您会看到?Foo@@YAXXZ
因此,C#程序中相应的声明应该是:
[DllImport("foo.dll", EntryPoint = "?Foo@@YAXXZ",
ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
private static extern void Foo();
<>有一些方法可以改变C++函数声明,使C语言声明更容易。这实际上不是一个好主意,这些修饰的名字实际上帮助捕捉错误。 < P> C++语言支持重载,就像C语言一样。您可以导出函数
voidfoo(int)
和函数voidfoo(double)
。显然,这两个函数不能同时导出为“Foo”,DLL的客户端不知道选择哪个函数。事实并非如此
C++编译器通过对函数名的修饰来解决这个问题。添加使Foo(int)不同于Foo(double)的额外字符。通过从列出导出函数名称的Visual Studio命令提示符运行
Dumpbin.exe/exports foo.dll
,可以看到这些修饰的名称。假设您的声明是相关的,您会看到?Foo@@YAXXZ
因此,C#程序中相应的声明应该是:
[DllImport("foo.dll", EntryPoint = "?Foo@@YAXXZ",
ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
private static extern void Foo();
<>有一些方法可以改变C++函数声明,使C语言声明更容易。这实际上不是一个好主意,这些修饰的名字实际上有助于捕捉错误。是<代码> FoE()/Cuth> C++中的全局函数,还是类成员方法?请注意,“方法”一词仅适用于类成员函数,而不适用于全局函数。也知道No.MangLig.IsCux> FooWoor()/Cuth> C++中的全局函数,还是类成员方法?请注意,“方法”一词仅适用于类成员函数,而不适用于全局函数。还要注意名字的曼格林格。注意,你可能还必须在C++的边上指定调用约定,因为C++默认为“代码> CCDLC< /Cord>”,但是PInvoke默认为“代码> STDCALL//CODE”。谢谢Rohan,这说明了。由于C++将默认为“代码> CDECL < /COD>,但是PInvoke默认为<代码> STDCALL> /COD>谢谢,Rohan,这说明了。如果C中的声明不匹配入口点字段会发生什么?如果
“?Foo@@YAXXZ”
是Foo(int)
,如果1.void Foo(double)
或2,会发生什么情况?示例中的“Foo()”是在C#中声明的?如果C#中的声明与入口点字段不匹配,会发生什么情况?如果“?Foo@@YAXXZ”
是Foo(int)
,那么如果1.void Foo(double)
或2,则会发生什么情况?示例中的“Foo()”是用C#声明的?
[DllImport("foo.dll", EntryPoint = "?Foo@@YAXXZ",
ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
private static extern void Foo();