我试图用C#app互操作C ++ DLL(dissasembly的好处),所以我用这样的导出符号创建了一个C ++ Win32项目(DLL):
LicensePolicy32.h:
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the LICENSEPOLICY32_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// LICENSEPOLICY32_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef LICENSEPOLICY32_EXPORTS
#define LICENSEPOLICY32_API __declspec(dllexport)
#else
#define LICENSEPOLICY32_API __declspec(dllimport)
#endif
LICENSEPOLICY32_API char* GetXmlTokenNode(void);
LicensePolicy32.cpp:
#include "stdafx.h"
#include "LicensePolicy32.h"
bool GetLicense()
{
DWORD dwType = REG_SZ;
HKEY hKey = 0;
char value[1024];
DWORD value_length = 1024;
LPCWSTR subkey = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\WSESecurityPolicy";
LONG openReg = RegOpenKeyEx(HKEY_LOCAL_MACHINE,subkey,0, KEY_WOW64_64KEY | KEY_QUERY_VALUE, &hKey);
if (openReg==ERROR_SUCCESS)
{
return true;
}
else
{
return false;
}
LONG getReg = RegQueryValueEx(hKey, L"WSEHostProcessID", NULL, &dwType, (LPBYTE)&value, &value_length);
if (getReg==ERROR_SUCCESS)
{
return true;
}
else
{
return false;
}
}
LICENSEPOLICY32_API char* GetXmlTokenNode()
{
char *orig;
bool resultLicense = GetLicense();
if (!resultLicense)
{
return "";
}
else
{
return "/{0}:Envelope/{0}:Header";
}
}
我的C#测试代码如下:
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
namespace TestDllConsoleApplication
{
class Program
{
[STAThread]
static void Main(string[] args)
{
Test testObj = new Test();
}
}
public class Test
{
[MarshalAs(UnmanagedType.LPStr)]
public string result;
[DllImport(@"D:\Proyectos\NET\Dll\LicensePolicy32\Release\LicensePolicy32.dll", CharSet=CharSet.Ansi, EntryPoint = "GetXmlTokenNode")]
public static extern string GetXmlTokenNode();
public Test()
{
try
{
result = GetXmlTokenNode();
result += " result";
}
catch (DllNotFoundException exDll)
{
string error = "Dll no encontrado";
}
catch (BadImageFormatException exBad)
{
string error = "Plataforma Ensamblado incompatible";
}
catch (Win32Exception exWin32)
{
string error = "Error general de Win32";
}
catch (EntryPointNotFoundException exPoint)
{
string error = "No encontró punto de entrada al método";
}
catch (Exception ex)
{
string error = "Error otros";
}
}
}
}
DLL的路径很好,但是当我运行C#时,测试项目会抛出EntryPointNotFoundException。
感谢您的帮助,谢谢
答案 0 :(得分:1)
这些不是您正在寻找的机器人。您的c ++名称将被装饰,实际名称将不是GetXmlTokenNode。要避免这种情况,请使用extern“C”作为要导出的方法的签名的一部分。这样可以避免名字装饰。
您可能会发现this whitepaper有用。
答案 1 :(得分:0)
C ++编译器为任何函数名添加后缀。后缀定义了参数类型和顺序 - 编译器可以处理重载的方式。
为了避免它,你可以使用C进行编译(将cpp后缀更改为C,如果代码中没有特殊的C ++功能,VS将会理解你想要做什么)。
或者找到本机DLL函数的真实名称,并将其用作入口点。