我正在尝试使用P/Invoke为本机c ++ .dll创建一个包装器.
.dll的源代码具有以下指定的入口点:
// .h-file
CHROMAPRINT_API ChromaprintContext *chromaprint_new(int algorithm);Run Code Online (Sandbox Code Playgroud)
方法实现:
// .cpp-file
ChromaprintContext *chromaprint_new(int algorithm)
{
ChromaprintContextPrivate *ctx = new ChromaprintContextPrivate();
ctx->algorithm = algorithm;
ctx->fingerprinter = new Fingerprinter(CreateFingerprinterConfiguration(algorithm));
return (ChromaprintContext *)ctx;
}Run Code Online (Sandbox Code Playgroud)
ChromaprintContextPrivate类型是一个结构:
>// .cpp-file
struct ChromaprintContextPrivate {
int algorithm;
Fingerprinter *fingerprinter;
vector<int32_t> fingerprint;
};Run Code Online (Sandbox Code Playgroud)
我的C#包装器代码:
// .cs-file
[System.Runtime.InteropServices.DllImportAttribute(
"libchromaprint.dll",
EntryPoint = "chromaprint_new")]
private static extern System.IntPtr chromaprint_new(int algorithm);
public static IntPtr Chromaprint_New(ChromaprintAlgorithm algorithm)
{
// Hardcoded parameter for testing
return chromaprint_new(0); // (int)algorithm
}Run Code Online (Sandbox Code Playgroud)
调用IntPtr ptr = Chromaprint_New(0);引发以下MDA异常:
调用PInvoke 函数'MyProject.ChromaprintWrapper!'MyProject.ChromaprintWrapper.LibChromaPrint :: chromaprint_new'使堆栈失衡.这很可能是因为托管PInvoke签名与非托管目标签名不匹配.检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配.
所以我理解问题是什么(堆栈上的条目数量不是预期的).我假设方法参数没问题int algorithm.我不确定返回类型.它应该是结构而不是指针吗?
我通过P/Invoke Interop Assistant运行.h文件获得了上面的C#代码.返回类型错了吗?它应该是什么?
什么是C#表示vector<int32_t> fingerprint;?
(见ChromaprintContextPrivate上面的结构.)
您很可能需要指定调用约定.
请尝试以下方法:
[System.Runtime.InteropServices.DllImportAttribute("libchromaprint.dll",
EntryPoint = "chromaprint_new",
CallingConvention=CallingConvention.Cdecl)]
Run Code Online (Sandbox Code Playgroud)
默认情况下,这使用Winapi(实际上是StdCall)来更容易调用Windows API,但这通常不是大多数C++库的默认设置.