C#中dllimport使用的c ++ unmanaged dll会产生入口点未找到错误

时间:2015-05-08 19:25:36

标签: visual-studio-2013 dllimport

我知道这个问题以前曾经多次被问过。我已经阅读了所有可以找到的问题以及stackoverflow之外的信息。到目前为止,我还没有找到答案,我可以弄清楚这将解决我遇到的具体问题。

这是非托管c ++ dll头文件的代码。

namespace MyWin32DLL
{
    class MyWin32ClassOne
    {

    public:
        static __declspec(dllexport) int Getvar();

    };
}

这是c ++ dll cpp文件的代码

#include "MyWin32ClassOne.h"

namespace MyWin32DLL
{

    int MyWin32ClassOne::Getvar()
    {
        return 123;
    }
}

这个代码我从各种来源汇总,所以它可能根本就不对。我对c ++或dll的经验不是很熟悉。

这是我愚蠢的小c#winforms prog的代码,我试图访问dll。 (编辑纠正类型不匹配,如评论中tolanj所指出的)

namespace TestDll
{
    public partial class Form1 : Form
    {

        [DllImport("MyWin32CppDll.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern int Getvar();

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string response = Getvar().ToString();

            MessageBox.Show(response, "title", MessageBoxButtons.OK);
        }
    }
}

现在,在这一点上,我明白我是因为c ++编译器破坏了方法和函数的名称而得到“无入口点”错误。

根据我的阅读,我可以做两件事来解决问题。

事1 在我的声明之前添加extern“c”,这样编译器就不会破坏名称。

namespace MyWin32DLL
{
    class MyWin32ClassOne
    {

    public:
        extern "C" static __declspec(dllexport) int Getvar();

    };
}

当我尝试这个时,我从Visual Studio收到错误,指出“不允许链接规范”。

好的,所以我尝试使用dumpbin找到我的函数的错位名称,并使用错位名称作为dllimport调用中的入口点。

所以我在我的dll上运行dumpbin / symbols而且我没有得到任何函数名,无法修改或以其他方式。

Dump of file mywin32cppdll.dll

File Type: DLL

  Summary

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

接下来我尝试dumpbin / exports

Dump of file mywin32cppdll.dll

File Type: DLL

Section contains the following exports for MyWin32CppDll.dll

00000000 characteristics
554CF7D4 time date stamp Fri May 08 13:52:20 2015
    0.00 version
       1 ordinal base
       1 number of functions
       1 number of names

ordinal hint RVA      name

      1    0 00011005 ?Getvar@MyWin32ClassOne@MyWin32DLL@@SAHXZ = @ILT+0(?Getvar@MyWin32ClassOne@MyWin32DLL@@SAHXZ)

Summary

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

看着我看不到要使用的受损或装饰名称。但作为一个拉特,我使用“Getvar @ MyWin32ClassOne @ MyWin32DLL @@ SAHXZ”作为我的入口点,并且仍然在我的c#程序中得到同样的错误。

显然我错过了什么。如何从我的c#程序访问dll函数?

1 个答案:

答案 0 :(得分:1)

正如您所观察到的,该名称已被破坏。您已设法在错位名称的开头省略?。您的导入应该是:

[DllImport("MyWin32CppDll.dll", CallingConvention = CallingConvention.Cdecl,
    EntryPoint = "?Getvar@MyWin32ClassOne@MyWin32DLL@@SAHXZ")]
public static extern int Getvar();

请注意您的函数使用cdecl调用约定。