我已经提供了一个由C#等人调用的DLL。 DLL包含两个方法如下
extern "C" {
__declspec(dllexport) BSTR GroupInit(LPCTSTR bstrIniFile, bool bDiagErr, bool bProcErr);
__declspec(dllexport) void G();
}
class GrouperServer {
public:
BSTR GroupInit(LPCTSTR bstrIniFile, bool bDiagErr, bool bProcErr);
void G();
}
BSTR GrouperServer::GroupInit(LPCTSTR bstrIniFile, bool bDiagErr, bool bProcErr) {
CString strResult = "";
char* sz;
SetVars(bDiagErr, bProcErr);
if (sz = ::GroupInit((char*)bstrIniFile, 1))
strResult = sz;
return strResult.AllocSysString();
}
void G() {
MessageBox(0, "And text here", "MessageBox caption", MB_OK);
}
我试图通过首先定义类来调用C#中的这些DLL:
public class GrouperServer {
[DllImport("GrouperServer.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void G();
[DllImport("GrouperServer.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.BStr)]
public static extern string GroupInit(
string strCmdFile, bool bAllowBadDiagCodes, bool bAllowBadProcCodes);
}
并且正在做
this.strCommandFilePath = "C:\\MyDir\\MyCommandFile.txt";
Grouper.GrouperServer.G();
Grouper.GrouperServer.GroupInit(this.strCommandFilePath, true, true);
对方法G()
的调用有效,我收到了一个消息框,但是对于GroupInit()
的调用,我得到了
DrGroupIN.exe中发生了未处理的“System.EntryPointNotFoundException”类型异常。附加信息:无法在DLL“GrouperServer.dll”中找到名为“GroupInit”的入口点。
在这种情况下,如何使用正确的参数调用第二个方法GrouInit(...)
?
修改1。
我也试过
[DllImport("GrouperServer.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr GroupInit(
string strCmdFile, bool bAllowBadDiagCodes, bool bAllowBadProcCodes);
通过以下方式调用:
IntPtr ptr = Grouper.GrouperServer.GroupInit(this.strCommandFilePath, true, true);
string strString = Marshal.PtrToStringBSTR(ptr);
Marshal.FreeBSTR(ptr);
但这也引发了上述错误。
编辑2。
我也试过
[DllImport("GrouperServer.dll", CallingConvention = CallingConvention.Cdecl, CharSet=CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.BStr)]
public static extern string GroupInit(
[MarshalAs(UnmanagedType.LPTStr)]string strCmdFile,
bool bAllowBadDiagCodes,
bool bAllowBadProcCodes);
但这也引发了上述错误。
答案 0 :(得分:2)
它看起来好像你不能使用C#调用这个DLL。 DLL导出类的成员函数。而你无法实例化那个类。
我可以看到以下选项:
尽管如此,这些声明似乎存在冲突:
extern "C" {
__declspec(dllexport) BSTR GroupInit(LPCTSTR bstrIniFile, bool bDiagErr, bool bProcErr);
__declspec(dllexport) void G();
}
class GrouperServer {
public:
BSTR GroupInit(LPCTSTR bstrIniFile, bool bDiagErr, bool bProcErr);
void G();
}
第一对声明似乎是非成员函数。但是它们之后是一个具有相同名称的成员函数的类。您需要清楚尝试调用哪些功能。
也许DLL已经包含了包含成员函数的非成员函数。在这种情况下,您只需要找出导出它们的名称。使用Dependency Walker来做到这一点。
那么,如何声明p / invoke。您需要知道正在使用的字符集以及导出函数的名称。我们假设是Unicode。 p / invoke将是:
[DllImport("GrouperServer.dll", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "<exported name goes here>")]
[return: MarshalAs(UnmanagedType.BStr)]
public static extern string GroupInit(
[MarshalAs(UnmanagedType.LPWStr)]
string strCmdFile,
bool bAllowBadDiagCodes,
bool bAllowBadProcCodes
);