在我的DLL中有一个我想要导出的方法.
//作品:
extern "C" __declspec(dllexport)
Run Code Online (Sandbox Code Playgroud)
//不会工作
__declspec(dllexport)
Run Code Online (Sandbox Code Playgroud)
C++导出:
extern "C" __declspec(dllexport) int Test();
Run Code Online (Sandbox Code Playgroud)
C#import:
[DllImport("CircleGPU2_32.DLL", EntryPoint = "Test",
CallingConvention = CallingConvention.StdCall)]
public static extern int Test();
Run Code Online (Sandbox Code Playgroud)
为什么我需要外部"C"?
gre*_*olf 24
这是由于C++完成了名称修改.
这里的例子是CFF Explorer为dll的导出表显示的内容.第一个是用borland的c ++编译器构建的.第二个是用msvc构建的.
Ordinal FunctionRVA Name RVA Name
00000001 0020E140 0032C2B6 createDevice
00000002 0020E244 0032C2C3 createDeviceEx
0000000D 00328DA4 0032C0C1 @irr@core@IdentityMatrix
0000000E 00328DE4 0032C28A @irr@video@IdentityMaterial
Run Code Online (Sandbox Code Playgroud)
0000000C 000F9C80 001EE1B6 createDevice
0000000D 000F9CE0 001EE1C3 createDeviceEx
00000001 00207458 001EDDC7 ?IdentityMaterial@video@irr@@3VSMaterial@12@A
00000002 001F55A0 001EDDF5 ?IdentityMatrix@core@irr@@3V?$CMatrix4@M@12@B
Run Code Online (Sandbox Code Playgroud)
第2个功能createDevice和createDeviceEx包含extern "C"签名在它的原型,而有的则没有.注意使用C++修改时的编码差异.差异实际上比这更深刻.
正如在其他的答案所解释的,C++标准并没有指定甲 bstract 乙 inary 我覆盖整个院落.这意味着设计他们的工具的供应商几乎可以做任何他们想要的事情,当涉及到如何处理函数调用以及如何在引擎盖下工作 - 只要它表现出标准所规定的预期行为.
使用所有这些不同的编码方案,其他语言无法使用C++编译的模块.用一个C++编译器编译的Heck模块不太可能与另一个一起工作!编译器供应商可以自行决定在版本之间自由更改编码.
此外,没有共同的ABI意味着没有共同的预期方式来调用这些函数/方法.例如,一个编译器可能会在堆栈上传递其参数,而另一个编译器可能会在寄存器上传递它.有人可能会从左到右传递论据,而另一个可能会被逆转.如果这些方面中的一个与调用者和被调用者之间不完全匹配,则您的应用程序将崩溃...即如果您很幸运.供应商不是通过强制执行不同编码的构建错误而不是处理此问题.
OTOH,虽然C也没有标准化的ABI,但通过比较,C是一种更简单的语言.大多数C编译器供应商以类似的方式处理函数修饰和调用机制.因此,即使标准中没有明确规定ABI,也存在某种"事实上"的标准.通过这种通用性,它使其他语言更容易与使用C编译的模块进行交互.
例如,__stdcall功能签名中的装饰被理解为遵循特定的调用约定.参数从右向左推,然后被调用者负责清理堆栈.__cdecl是类似的,但据了解,调用者负责清理堆栈.
如果有问题的模块必须能够与C++以外的语言互操作,那么适当地进行装饰并将其作为C API公开是最好的选择.请注意,这样做可以放弃一些灵活性.特别是,您将无法重载这些函数,因为编译器无法再为名称重整的每个重载生成唯一符号.
如果互操作性对于所讨论的模块并不重要 - 它只会与它构建的同一工具一起使用,那么就会省略extern "C"原型中的装饰.
Dav*_*nan 11
主要原因是阻止C++名称管理器修改函数的名称.
尝试导出它而不用extern "C"并在Dependency Walker中检查生成的DLL,您将看到导出函数的完全不同的名称.
| 归档时间: |
|
| 查看次数: |
14061 次 |
| 最近记录: |