【发布时间】:2012-10-21 08:54:44
【问题描述】:
我有一个开源 C++ DLL
实际上它是来自 CRX 扩展的插件 dll,我试图在 Visual Studio 中使用 C# 调用它的函数
此扩展是 Google chrome-screen-capture
我设法创建了与 DLL 对话的代码,但我不知道如何调用它的函数。
这是我的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private class Sample
{
public Int32 length;
public String value;
}
[DllImport("C:\\Users\\Ofir\\Documents\\Visual Studio 2010\\Projects\\ConsoleApplication1\\ConsoleApplication1\\bin\\Debug\\screen_capture.dll")]
private static extern void NP_Initialize();
static void Main(string[] args)
{
Sample s = new Sample();
s.length = 0;
s.value = "Huhu";
NP_Initialize(); <-- I get an ERROR here :
}
}
}
错误:检测到 PInvokeStackImbalance 消息:对 PInvoke 的调用 功能 'ConsoleApplication1!ConsoleApplication1.Program::NP_Initialize' 有 堆栈不平衡。这可能是因为托管的 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数匹配 目标非托管签名。
我能做什么?
编辑:例如,如果我使用 NP_GetEntryPoints(),它将请求一个类型为 NPPluginFuncs 的指针。
例如:NPError WINAPI NP_GetEntryPoints(NPPluginFuncs* pFuncs)
这是它要求的类型:
typedef struct _NPPluginFuncs {
uint16 size;
uint16 version;
NPP_NewUPP newp;
NPP_DestroyUPP destroy;
NPP_SetWindowUPP setwindow;
NPP_NewStreamUPP newstream;
NPP_DestroyStreamUPP destroystream;
NPP_StreamAsFileUPP asfile;
NPP_WriteReadyUPP writeready;
NPP_WriteUPP write;
NPP_PrintUPP print;
NPP_HandleEventUPP event;
NPP_URLNotifyUPP urlnotify;
JRIGlobalRef javaClass;
NPP_GetValueUPP getvalue;
NPP_SetValueUPP setvalue;
} NPPluginFuncs;
但我不知道如何构建这种类型并发送它。 我想完成在 IE 工具栏中构建一个函数,然后使用这个 DLL 中的函数。 这样我就可以在 IE 中使用屏幕截图了。
EDIT2:当我调用 NP_Shutdown() 函数时,它就可以了。 一切都很清楚,没有例外。 所以我想这都是我发送给另一个函数的类型。 但是我怎么发送这种类型的呢?
【问题讨论】:
-
NP_Initialize应该带参数吗? It looks like it,并且在期望它们时不传递它肯定会使堆栈失衡。您可以将CallingConvention排除在您的DllImport之外——这些函数被声明为WINAPI,这意味着默认调用约定很好,实际上使用Cdecl会给您带来问题。 -
Ofear,如果你真的有
no idea,那么最好的起点是the documentation on pinvoke marshalling。如果您需要特定部分的帮助,请更新您的问题。 -
感谢您的 cmets,我的问题是制作这个 _NPPluginFuncs 对象并将其发送给函数...