C# 无法获取要在.net中运行的MFC dll函数

C# 无法获取要在.net中运行的MFC dll函数,c#,c++,.net,dll,mfc,C#,C++,.net,Dll,Mfc,我试图创建一个简单的MFC DLL,导出它的函数并在C#.net项目中使用 在下面的代码中,我在DLL中有两个方法,我把海报的建议带到了原始问题。我正在重新发布当前代码,我得到了错误 {“找不到名为“\u Worker”的入口点_Create@0'在DLL'C:\Users\mspath\Documents\MDS\u SIMCA\DevSIMCA\u DLL\TestDLL\Debug\MFClib.DLL'。“:”“} 我已使用dumpbin.exe获得正确的损坏名称 mfcdll.cpp

我试图创建一个简单的MFC DLL,导出它的函数并在C#.net项目中使用 在下面的代码中,我在DLL中有两个方法,我把海报的建议带到了原始问题。我正在重新发布当前代码,我得到了错误

{“找不到名为“\u Worker”的入口点_Create@0'在DLL'C:\Users\mspath\Documents\MDS\u SIMCA\DevSIMCA\u DLL\TestDLL\Debug\MFClib.DLL'。“:”“}

我已使用dumpbin.exe获得正确的损坏名称

mfcdll.cpp mfcdll.h 班主任 { 公众: 工人(无效); ~工人(无效)

})

MFCLib.cpp C#net

你必须在C++类之外声明外部的“C样式”函数。一种方法是通过管道将调用传递给类:

__declspec(dllexport) int DoMath (int iOne, int iTwo)
{
    Worker* worker = new Worker();
    int i = worker-> DoMath(iOne, iTwo);
    delete worker;
    return i;
}
< >或将C++类转换为C++/CLI类,并将库导入托管库而不是非托管库。


免责声明:我的C++是生锈的,所以我可能在语法和/或正确的内存管理上有点偏离。

你的调用约定是错误的。declspec(dllexport)仅使函数导出,而不使其具有标准调用约定。我会将u stdcall或WINAPI添加到函数签名中,以便它们使用标准调用。您的一个函数之所以能够工作,是因为它没有参数可以传递或从堆栈中弹出。

是的,我尝试使用extren“c”,只使用简单的名称和相同的错误
GetInteger
DoMath
是类
Worker
的实例函数,最简单的方法是在DLL中创建一个非实例函数来创建实例并返回结果,否则您必须找到一种方法来创建
Worker
的实例,然后在其上运行这些函数。事实上,它们不是DLL的入口点,不能单独运行。您可以总是使用CLR项目来连接C++与C++。@ SHR:您可能指的是C++/CLI.
/clr
是编译C++/CLI的编译器命令行选项,而不是项目类型。您还需要指定调用约定。由于问题中的托管代码正在使用
调用convention.StdCall
,因此它应该是
\uuu declspec(dllexport)int\uu StdCall DoMath(int iOne,int iTwo)
。向函数签名中添加\uu StdCall并不能解决此问题。我将尝试上面关于创建工人类objectOk的建议,我正在尝试了解如何让这个dll工作。我采纳了D斯坦利建议的“管道”建议。我想我误解了他的意思,但是我在MFCLib类中创建了一个方法来创建一个Worker对象并调用DoMath函数。这给了我同样的失败。extern“C”{uuu declspec(dllexport)void*.\uu stdcall Worker\u Create(){return new Worker();}uu declspec(dllexport)void*.\uu stdcall Worker\u Destroy(Worker*实例){delete实例;return实例;}.\uu declspec int(dllexport)int{uu stdcall Worker\u DoMath(Worker*实例,inti,intj)上面的{return instance->DoMath(i,j);}}代码在DLL中,我尝试在C#代码中调用,并得到“找不到名为'\u Worker'的入口点”_Create@0“在这里!
static int GetInteger ();
static int DoMath (int iOne, int iTwo);
extern "C"
{
    __declspec(dllexport) void * __stdcall Worker_Create()
    {
        return new Worker();
    }

    __declspec(dllexport) void  * __stdcall Worker_Destroy(Worker * instance)
    {
        delete instance;
        instance = 0;
        return instance;
    }

    __declspec(dllexport) int __stdcall Worker_DoMath(Worker * instance, int i, int j)
    {
        return instance->DoMath(i, j);
    }
}
   public partial class MainWindow : Window
    {
/*
 *          from dumbin.exe /exports:
 *          
          1    0 00011519 _Worker_Create@0 = @ILT+1300(_Worker_Create@0)
          2    1 00011230 _Worker_Destroy@4 = @ILT+555(_Worker_Destroy@4)
          3    2 000110D2 _Worker_DoMath@12 = @ILT+205(_Worker_DoMath@12)
*/
        [DllImport("C:\\Users\\mspath\\Documents\\MDS_SIMCA\\DevSIMCA_Dll\\TestDLL\\Debug\\MFClib.dll",
                EntryPoint = "_Worker_Create@0",
                ExactSpelling = false,
                CallingConvention = CallingConvention.StdCall)]
        public extern static IntPtr Worker_Create();

        [DllImport("C:\\Users\\mspath\\Documents\\MDS_SIMCA\\DevSIMCA_Dll\\TestDLL\\Debug\\MFClib.dll",
                EntryPoint = "_Worker_Destroy@4",
                CallingConvention = CallingConvention.StdCall)]
        public extern static IntPtr Worker_Destroy(IntPtr iptr);

        [DllImport("C:\\Users\\mspath\\Documents\\MDS_SIMCA\\DevSIMCA_Dll\\TestDLL\\Debug\\MFClib.dll",
                EntryPoint = "_Worker_DoMath@12",
                CallingConvention = CallingConvention.StdCall)]
        public extern static int Worker_DoMath(IntPtr instance, int i, int j);

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            IntPtr instance = Worker_Create();

            int i = Worker_DoMath(instance, 4, 2);

            Worker_Destroy(instance);
        }
    }
__declspec(dllexport) int DoMath (int iOne, int iTwo)
{
    Worker* worker = new Worker();
    int i = worker-> DoMath(iOne, iTwo);
    delete worker;
    return i;
}