【问题标题】:Entry point not found on DLL importDLL 导入时找不到入口点
【发布时间】:2018-09-21 09:08:28
【问题描述】:

尝试使用来自 C# 的第三方本机 DLL,我得到了找不到 DLL 入口点的异常,我不知道是什么原因。

dumpbin /exports 给了我以下符号:?Foo@@YA_NPBDII0II_NMEEE01PAE@Z。我用undname 解决了这个问题,它返回:bool __cdecl Foo(char const *,unsigned int,unsigned int,char const *,unsigned int,unsigned int,bool,float,unsigned char,unsigned char, unsigned char,char const *,bool,unsigned char*)

因此,我尝试像这样导入函数:

[DllImport("FooDll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] // evtl. __thiscall?, Charset?
    private static extern bool Foo(string name, uint x, uint y, string app, uint width, uint height, bool switch, double factor,
        byte r1, byte g1, byte b1, string store, bool switchBack, [In, Out] byte[] result);

我也尝试使用CallingConvention = CallingConvention.ThisCall 并且不使用 charset 参数,但发生了同样的异常。

知道去哪里看吗?

【问题讨论】:

  • 如果我没记错的话,如果 dll 不是用EXTERN "C" 编译的,LoadLibrary 不会自动处理 mangling。这意味着您应该使用损坏的名称加载函数。让我们知道这是否有帮助。
  • @WiktorZychla 设置了EntryPoint = "?Foo@@YA_NPBDII0II_NMEEE01PAE@Z" 我收到了AccesViolationException 所以我猜这意味着该函数被调用,但其他原因导致另一个问题
  • 查阅库的文档以了解如何调用它
  • @DavidHeffernan 不幸的是没有这样的文档。否则,我就不需要在这里问问题了
  • 关闭,但没有雪茄。入口点是必需的,双精度应该是浮点数。现在堆栈帧关闭了 4,因此当它尝试访问结果参数时,它会倒下。小心那个数组,似乎没有办法告诉它它有多大,所以你必须猜测所需的大小。猜测太低会破坏 GC 堆,非常讨厌。志存高远。

标签: c# pinvoke dllimport


【解决方案1】:

感谢Wiktor和Hans的帮助,解决了入口点问题:

有必要为DllImport 属性指定一个入口点作为参数,并带有修饰/修饰的名称,因为看起来DLL 不使用extern C 声明。此外,factor 参数的类型必须是 float (System.Single) 以匹配堆栈上的预期参数长度。所以 C# 代码现在看起来像这样:

[DllImport("FooDll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "?Foo@@YA_NPBDII0II_NMEEE01PAE@Z")]
private static extern bool Foo(string name, uint x, uint y, string app, uint width, uint height, bool switch, float factor,
    byte r1, byte g1, byte b1, string store, bool switchBack, [In, Out] byte[] result);

【讨论】:

    猜你喜欢
    • 2012-12-08
    • 1970-01-01
    • 1970-01-01
    • 2015-07-19
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    • 2011-06-07
    相关资源
    最近更新 更多