我在C ++ dll上进行P / Invoke调用时遇到了一些困难。我得到“无法找到入口点”错误。
在C ++中,我正在公开这样的函数......
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport)
long
WINAPI
MgScSCardUIDlgSelectCardW(__inout LPOPENCARDNAMEW_EX pOcne);
#ifdef __cplusplus
}
#endif
C#中的dllimport语句如下:
[DllImport("mgsc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public static extern Int32 MgScSCardUIDlgSelectCardW([MarshalAs(UnmanagedType.Struct)] [In, Out] ModWinsCard.OPENCARDNAME_EX ocnwex);
我没有调用约定,标准和winapi调用约定。与所有人的结果相同。我用DependencyWalker查看了暴露的函数,并将其暴露为“_MgScSCardUIDlgSelectCardW @ 4”。我理解装饰是正常的(但是声明'extern'C“'应该处理那个??),但是从来没有看到任何示例代码,其中dllimport有这样的功能,所以它似乎不是这就是我应该如何称呼它。
我在这里看到了推荐.def文件的答案,但我宁愿不必处理这个问题,因为这只是我学习和搞砸的另一件事,当我需要完成这件事时
答案 0 :(得分:1)
DLL的一切正常。您正在从编译器添加到名称的@ 4后缀中获益。它描述了传递给函数的参数值的大小,结构指针的4个字节。这可以捕获客户端代码中函数声明中的错误,这种不匹配可能非常难以排除故障,因为它们会使堆栈失衡。
这里也很好用,你几乎肯定宣称这个功能错了。将OPENCARDNAME_EX声明为结构而不是类的概率为99%。这要求您通过引用而不是通过值传递参数。 [MarshalAs]属性也是错误的。修正:
[DllImport("mgsc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 MgScSCardUIDlgSelectCardW(ref ModWinsCard.OPENCARDNAME_EX ocnwex);