P/调用,查找/声明函数入口点时遇到问题

P/Invoke, trouble finding/declaring function entry point

本文关键字:问题 入口 遇到 声明 调用 查找 函数      更新时间:2023-10-16

我在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 文件的答案,但我宁愿不必处理这个问题,因为当我只需要完成这项工作时,这只是我要学习和搞砸的另一件事。

DLL一切正常。 您将获得编译器添加到名称中的 @4 后缀的好处。 它描述了传递给函数的参数值的大小,结构指针为 4 个字节。这会捕获客户端代码中函数声明中的错误,此类不匹配可能很难排除故障,因为它们会使堆栈不平衡。

这在这里也很好用,你几乎可以肯定声明函数是错误的。 您声明OPENCARDNAME_EX为结构而不是类的几率为 99%。 这要求您通过引用而不是值传递参数。 [元帅]属性也是错误的。 修复:

[DllImport("mgsc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 MgScSCardUIDlgSelectCardW(ref ModWinsCard.OPENCARDNAME_EX ocnwex);