我有一个本机C ++函数,我必须从我的C#代码调用,C ++函数看起来像这样:
__declspec(dllexport) int getCameraFrame(void *buffer);
在C ++中调用函数如下所示:
unsigned char* data = new unsigned char[640 * 480 * 4];
getCameraFrame(data);
从C#我用PInvoke导入函数:
[DllImport("CameraSDK.dll")]
public static extern int getCameraFrame(???);
我在这里使用什么作为参数,以及如何从我的C#代码调用该函数?
byte[] buffer;
getCameraFrame(out buffer); //???
更新
我尝试使用string,byte [],char [],IntPtr作为参数,但我一直得到PInvokeStackImbalance异常。
调用PInvoke函数' Test!Test.Form1 :: getCameraFrame'具有 堆栈不平衡。这可能是因为托管PInvoke 签名与非托管目标签名不匹配。检查一下 调用约定和PInvoke签名匹配的参数 目标非托管签名。
更新 - 解决了
大卫和迈克尔给出了答案,我已经设法通过以下代码解决了我的问题
[DllImport("CameraSDK.dll", CallingConvention.Cdecl)]
public static extern int getCameraFrame([Out] StringBuilder buffer);
StringBuilder data = new StringBuilder(1024 * 768 * 4)
int result = getCameraFrame(data);
大卫,你的回答确实是正确的,请注意我的StringBuilder init是1024 * 768 * 4(而不是640 * 480 * 4 - 这就是抛出AccessViolationException的原因) - 在C ++代码中缓冲区的缩放( 1024 * 768 * 4)到(640 * 480 * 4) - 我一定错过了那部分,所以,那是我的坏事。
我能够获取原始数据,但无法将其转换为位图(原始数据采用某种奇怪的格式),但这是另一个问题。
由于
答案 0 :(得分:1)
我有以下工作代码:
C ++定义:
__declspec(dllexport) void SendRenderedImage(byte buffer[]);
C#声明
[DllImport("External.dll", EntryPoint = "SendRenderedImage", CallingConvention = CallingConvention.Cdecl)]
public static extern void SendRenderedImage(
[MarshalAs(UnmanagedType.LPArray)] byte[] buffer
);
C#用法:
SendRenderedImage(new byte[10]);
希望它有所帮助。
答案 1 :(得分:0)
我这样声明:
[DllImport(dllname, CallingConvention = ???)]
public static extern int getCameraFrame(
[Out] byte[] buffer
);
像这样调用函数:
byte[] data = new byte[640 * 480 * 4];
int retval = getCameraFrame(data);
请注意,您需要确定调用约定。从表面上看,它看起来像cdecl。
我使用[Out]
属性来指示数据从被叫方流向调用方。但是,由于编组器只是固定阵列,因此没有明显的影响。它至少记录了未来读者的意图。
<强>更新强>
您在评论中说您在使用此代码时遇到访问冲突。根据您提供的信息,此处的代码是准确的。因此,问题必须是我们看不到的问题。也许图书馆尚未初始化。也许功能是实例方法。或许还有一些其他问题无法辨别。
您需要超越问题中显示的内容。如果我在你的位置,我首先要制作一个使用该库的完整C ++程序,以证明该库有效并且您知道要进行的调用序列。然后我将其转换为C#。