【问题标题】:'System.EntryPointNotFoundException' when trying to call unmanaged function from C#尝试从 C# 调用非托管函数时出现“System.EntryPointNotFoundException”
【发布时间】:2012-03-06 16:41:50
【问题描述】:

我终于有了一个完整的 C++ DLL,但我无法从 C# 调用它。肯定会找到 DLL,因为当我从文件夹中删除它时,我得到了一个不同的异常,“DLLNotFoundException”。完整的错误描述是“无法在 DLL 'CComms.dll' 中找到名为 'GetNewInstance' 的入口点”。这些函数都像这样在 C++ 中导出

__declspec(dllexport) DWORD __stdcall GetNewInstance();

我像这样从 C# 调用它

[DllImport("CComms.dll")]
private static extern uint GetNewInstance();
// ... and in main
uint inst = GetNewInstance();

当我使用“dumpbin /exports CComms.dll”时,我得到了一些奇怪的输出,我不确定函数名是否被破坏,这就是它找不到入口点的原因

7    6 00002FB0 ?GetNewInstance@@YGKXZ = ?GetNewInstance@@YGKXZ (unsigned long
__stdcall GetNewInstance(void))   

我尝试使用 __cdecl 代替 __stdcall,结果相同。我已经接近完成这个项目了,我一直在寻找,希望这是我的最后一件事。

谢谢。

【问题讨论】:

  • 我看到你提到“CComms.dll”,但 DllImport 属性似乎在寻找“VLTGLSCommsDLL.dll”。这有什么不对吗?
  • "函数都像这样在 C++ 中导出" 您可以尝试在导出声明中添加extern "C" 以获得通常的__stdcall 导出名称?如果 .NET 不能同时导入这两种类型,我会感到惊讶。
  • 真的吗?我会说这是一个 C++ 修改。我希望 C __stdcall mangling 是 _GetNewInstance@0
  • ...抱歉,我的意思是 C++ __stdcall 重整。 __thiscall 是 C++ 方法调用约定。
  • 您的 C++ 被声明为无符号长整数,但您的 C# 代码只是无符号整数。您的调用约定也不匹配....这是一个问题。

标签: c# c++ dll dllimport


【解决方案1】:

您有两种创建 DLL 的方法。

一种是通过获取函数的地址(老式方式),第二种是通过参数和名称(“新”方式,例如 .net 使用的方式)。

我想你没有正确使用你的 C++ dll

也许你应该使用GetProcAddress GetProcAddress Msdn

这里有一些关于 Dll exportation 的文档,可能会有用

【讨论】:

    【解决方案2】:

    VB.NE也有同样的问题 如果函数声明时没有 __stdcall 但有托管调试助手“PInvokeStackImbalance”警告,则不会出现此异常。

    在声明的库函数中

    extern "C"  _declspec(dllexport)
    int __stdcall GetLine(HWND hwnd, int iLine, TCHAR *buff)
    

    将exports.def文件添加到dll项目中

    EXPORT
      GetLine
    

    和链接器的附加选项

    /DEF:"exports.def"
    

    问题解决了

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多