1

オープンソースの C++ DLL を持っています

実際には、CRX 拡張機能のプラグイン dll であり、Visual Studio With 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() 関数を呼び出しているときは問題ありません。すべてが明確で、例外はありません。だから私はそれがすべて私が他の関数に送るタイプにあると思います。しかし、この種のタイプをどのように送信しますか?

4

1 に答える 1

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です...

于 2014-11-24T14:51:22.617 に答える