我知道这个问题以前曾经多次被问过。我已经阅读了所有可以找到的问题以及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函数?
答案 0 :(得分:1)
正如您所观察到的,该名称已被破坏。您已设法在错位名称的开头省略?
。您的导入应该是:
[DllImport("MyWin32CppDll.dll", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "?Getvar@MyWin32ClassOne@MyWin32DLL@@SAHXZ")]
public static extern int Getvar();
请注意您的函数使用cdecl调用约定。