使用DlImport,Entrypoint从C#调用C语言中的C函数

我已经阅读了几个与我有关的问题,但多个答案都没有对我有用.

我需要从非托管DLL调用一个函数.我在SysWow64中有32位版本的DLL,在system32中有64位版本.无论如何,我正在编译x86.我没有DLL的源代码,因此使用extern“C”重新编译不是一个选项.

DLL的包含文件的相关部分:

(...)
#include <string>
namespace SomeNamespace
{
    (...)
    typedef std::wstring STRING;
    (...)
    class SomeClass
    {
        (...)
        static bool SomeFunc(const STRING& p1, bool p2);
        (...)
    }
}

当调用SomeFunc时,我得到一个例外:“找不到名为’?’的入口点在DllName.dll“(翻译是我的,可能是不准确的).

我在C#中的声明:

    [System.Runtime.InteropServices.DllImport("DllName.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?SomeFunc@SomeClass@SomeNamespace@@SA_NABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@_N@Z")]
bool SomeFunc(string p1, bool p2);

我也尝试过以下方法:

[System.Runtime.InteropServices.DllImport("DllName.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "#15")]
bool SomeFunc(string p1, bool p2);

15是根据Depends的函数序数,第一个版本中的EntryPoint也是从Depends获得的.

根据undname.exe,这是该函数的原始声明:

public: static bool __cdecl SomeFunc(class ?? :: ?? ::Z::basic_string<wchar_t,str
uct std::char_traits<wchar_t>,class w::allocator<wchar_t>,td,bool> const &, ?? )
 throw( ?? )

它似乎没有正确解析它; bool应该是FuncName的参数,而不是basic_string的类型参数.但是,我不确定这是否只是来自undname.exe的解析错误或更严重的问题.

我该如何解决?

更新:当使用函数的序号作为入口点时,我没有得到异常.我从Form的Load事件中调用它,在调试时,我丢失了控件.我的意思是,我正在调试SomeFunc()行上的光标,我点击F10,应用程序继续,好像我没有调试.我没有得到ThreadException或UnhandledException.

调用代码:

public bool CallSomeFunc()
{
    try
    {
        SomeFunc("p1", true);
    }
    catch (Exception ex)
    {
        ex.ToString(); // I just use this to put a breakpoint while debugging.
    }
    return true;
}

结束更新

最佳答案 您需要C/C++LI作为包装来从C类调用方法.

PInvoke仅适用于全局导出函数.

看看C++/CLI wrapper for native C++ to use as reference in C#.

点赞