我如何在C#中与C ++ NPAPI dll交谈?

时间:2012-10-21 08:54:45

标签: c# dllimport npapi

我有一个开源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类型的指针。

的exaple: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()函数时,没关系。 一切都很清楚,没有例外。 所以我想这是我发送给其他功能的类型。 但我怎么送这种类型的?

1 个答案:

答案 0 :(得分:1)

这是一个老问题,但我最近做了一些NPAPI的小型游览,所以我分享了我的发现。虽然我无法测试你的情况,但我会这样做。
首先声明_NPPluginFuncs结构:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct _NPPluginFuncs
{
    UInt16 size;
    UInt16 version;
    IntPtr newp;
    IntPtr destroy;
    IntPtr setwindow;
    IntPtr newstream;
    IntPtr destroystream;
    IntPtr asfile;
    IntPtr writeready;
    IntPtr write;
    IntPtr print;
    IntPtr @event;
    IntPtr urlnotify;
    IntPtr javaClass;
    IntPtr getvalue;
    IntPtr setvalue;
    IntPtr gotfocus;
    IntPtr lostfocus;
    IntPtr urlredirectnotify;
    IntPtr clearsitedata;
    IntPtr getsiteswithdata;
    IntPtr didComposite;
}

然后声明PInvoke调用:

[System.Runtime.InteropServices.DllImport("C:\\Users\\Ofir\\Documents\\Visual Studio 2010\\Projects\\ConsoleApplication1\\ConsoleApplication1\\bin\\Debug\\screen_capture.dll")]
private static extern void NP_Initialize(ref _NPPluginFuncs nPPluginFuncs);

[System.Runtime.InteropServices.DllImport("C:\\Users\\Ofir\\Documents\\Visual Studio 2010\\Projects\\ConsoleApplication1\\ConsoleApplication1\\bin\\Debug\\screen_capture.dll")]
private static extern IntPtr NP_GetEntryPoints(ref _NPPluginFuncs nPPluginFuncs);

[System.Runtime.InteropServices.DllImport("C:\\Users\\Ofir\\Documents\\Visual Studio 2010\\Projects\\ConsoleApplication1\\ConsoleApplication1\\bin\\Debug\\screen_capture.dll")]
private static extern void NP_Shutdown();

最后,请致电NPAPI:

_NPPluginFuncs nPPluginFuncs = new _NPPluginFuncs();
NP_Initialize(ref nPPluginFuncs);   // all members are 0 (IntPtr.Zero) after the call
IntPtr res = NP_GetEntryPoints(ref nPPluginFuncs);  // memory addresses filled in
NP_Shutdown();

您能否确认这是否适合您?您前面还有另一项重大任务:调用IntPtr返回的NP_GetEntryPoints个函数...