C#中的DllImport、MFC扩展DLL和名称混淆

3

我有一个MFC扩展DLL,我想在C#应用程序中使用它。我要暴露的函数是C函数,即我像这样导出它们:

extern "C"
{
 __declspec(dllexport) bool Initialize();
}

这些函数在内部使用MFC类,那么我该如何使用P/Invoke在C#中使用DLL。

其次,我想使用函数重载,但据我所知C不支持函数重载,如果我导出C++函数它们将被混淆。那么我该怎么解决这个问题呢?我们可以使用DllImport导入C++混淆函数。

2个回答

10

在头文件中有这个声明:

__declspec(dllexport) int fnunmanaged(void);
__declspec(dllexport) int fnunmanaged(int);
你可以使用 dumpbin.exe 来获取函数的确切名称:
dumpbin.exe /exports unmanaged.dll

Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file unmanaged.dll

File Type: DLL

  Section contains the following exports for unmanaged.dll

    00000000 characteristics
    4B0546C3 time date stamp Thu Nov 19 14:23:15 2009
        0.00 version
           1 ordinal base
           2 number of functions
           2 number of names

    ordinal hint RVA      name

          1    0 0001106E ?fnunmanaged@@YAHH@Z = @ILT+105(?fnunmanaged@@YAHH@Z)
          2    1 00011159 ?fnunmanaged@@YAHXZ = @ILT+340(?fnunmanaged@@YAHXZ)

  Summary

        1000 .data
        1000 .idata
        2000 .rdata
        1000 .reloc
        1000 .rsrc
        4000 .text
       10000 .textbss

在声明函数时使用这个名称:

[DllImport(@"D:\work\unmanaged.dll",
    EntryPoint = "?fnunmanaged@@YAHH@Z",
    ExactSpelling = true)]
static extern int fnunmanaged();

[DllImport(@"D:\work\unmanaged.dll",
    EntryPoint = "?fnunmanaged@@YAHXZ",
    ExactSpelling = true)]
static extern int fnunmanaged(int a);

另一种选择是使用模块定义文件:

LIBRARY "unmanaged"
EXPORTS 
  fn1=?fnunmanaged@@YAHH@Z
  fn2=?fnunmanaged@@YAHXZ

在这种情况下,您不再需要使用__declspec(dllexport),您的头文件可能看起来像这样:

int fnunmanaged(void);
int fnunmanaged(int);

最后将它们导入:

[DllImport(@"D:\work\unmanaged.dll")]
static extern int fn1();

[DllImport(@"D:\work\unmanaged.dll")]
static extern int fn2(int a);

这个答案对我非常有帮助。 - Abe Voelker

2

MFC扩展DLL需要调用者中的CWinApp对象,但在C#中没有这个对象。 可以使用MFC常规DLL对该DLL进行包装,从而拥有一个CWinApp对象。


你是什么意思?能否请你解释一下? - akif

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接