我使用DLL导出查看器尝试查找此DLL中的函数,我找到了一个函数列表,它在这里:
public: int __thiscall CSTVdsDisk::GetPartitionCount(void);
问题出在C#中我无法使用以下任何一种方法调用该函数:
[DllImport("Some.dll",
ExactSpelling = true,
EntryPoint = "GetPartitionCount",
CallingConvention = CallingConvention.StdCall,
SetLastError = true)]
或:
[DllImport("Some.dll",
ExactSpelling = true,
EntryPoint = "CSTVdsDisk::GetPartitionCount",
CallingConvention = CallingConvention.StdCall,
SetLastError = true)]
private static extern int GetPartitionSize();
他们都失败了。有什么我做错了吗?有人可以帮忙吗?谢谢!
答案 0 :(得分:2)
您不能使用P / Invoke调用该函数。 __thiscall调用引用意味着此函数是类成员函数。它是CSTVdsDisk
类的成员函数。
为了能够调用该函数,您必须创建CSTVdsDisk
类的实例并从该实例调用GetPartitionCount
。
您必须在C ++或C ++ / CLR中执行此操作,因为您无法在C#中创建C ++类。另请参阅Create unmanaged c++ object in c#。
答案 1 :(得分:1)
基于名称,这似乎是一个C ++类方法。这将使得直接从P / Invoke调用该方法变得非常困难有两个原因:
@0GetPartitionCount@CSTVdsDisk@@QPBAEXA
或类似名称。您可能需要使用dumpbin
等较低级别的工具来查找该名称。??
开头,如`?? 0CSTVdsDisk @@ QAE @ ABV0 @@ Z This CodeProject article向您展示了如何做到这一点,但它非常脆弱,所以期待出现问题。我强烈建议你找一个类似的非C ++库,或者至少有一个可以从C代码中使用的库。
答案 2 :(得分:0)
在您的本机代码中,确保您正在导出该功能。默认情况下,您的函数不会在Exports表中列出,因此您需要对其进行标记,以便编译器知道将其导出。您还需要将该功能标记为 外部“C” 这样编译器就不会破坏名称。
通常我定义以下宏:
#define DLLEXPORT extern "C" __declspec(dllexport)
处理所有这些,然后简单地声明导出的函数,如:
DLLEXPORT __cdecl int Example(int x, int y)
如果您发现您仍然遇到名称问题,请尝试在dll上使用免费的PE资源管理器程序,并检查导出的函数表中是否有正确的名称。