1

I have an open source C++ DLL

actually it's a plugin dll from a CRX extension that i'm trying to call it's function in Visual Studio With C#

This extension is a Google chrome-screen-capture

I manage to create the Code that talked with the DLL But i have no idea how to call it's functions.

This is my CODE:

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 : 
        }
    }
}

ERROR : PInvokeStackImbalance was detected Message: A call to PInvoke function 'ConsoleApplication1!ConsoleApplication1.Program::NP_Initialize' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

What can i do?

EDIT: For Example if i use NP_GetEntryPoints() it will request a pointer with the type of NPPluginFuncs.

Exaple:NPError WINAPI NP_GetEntryPoints(NPPluginFuncs* pFuncs)

This is the type it's request:

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;

But i have no idea how to build this type and send it. I want to accomplish to build a function in IE toolbar and then use the functions in this DLL . This way i can use the screen-capture in IE.

EDIT2: WHEN i'm calling the NP_Shutdown() function it's OK. everything is clear and no exception is popping out. so i guess it's all in the type that i send to the other function. but how would i send this kind of type?

Ofir Hadad
  • 1,800
  • 3
  • 26
  • 47
  • 1
    Is `NP_Initialize` supposed to take parameters? [It looks like it](https://developer.mozilla.org/en-US/docs/NP_Initialize), and not passing it any when it's expecting them definitely will unbalance the stack. You can leave `CallingConvention` out of your `DllImport` - those functions are declared as `WINAPI`, meaning that the default calling convention is fine, and in fact using `Cdecl` will give you problems. – anton.burger Oct 21 '12 at 09:39
  • Ofear, if you really have `no idea`, then the best place to start is [the documentation on pinvoke marshalling](http://msdn.microsoft.com/en-us/library/fzhhdwae.aspx). If you need help with a specific part of it, please update your question. – anton.burger Oct 22 '12 at 11:54
  • Thanks for your comments, my problem is to make this _NPPluginFuncs object and send this to the function... – Ofir Hadad Oct 22 '12 at 12:05

1 Answers1

1

This is an old question, but I recently did some small excursion into NPAPI, so I share my findings. Though I cannot test your case, but I'd go this way.
Firstly declare a _NPPluginFuncs structure:

[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;
}

Then declare PInvoke calls:

[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();

Finally, call the 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();

Can you confirm if this works for you? There will be another big task ahead of you: calling those IntPtr functions that NP_GetEntryPoints returned...

Peter Ivan
  • 1,467
  • 2
  • 14
  • 27
  • 1
    Thanks you Peter Ivan for this answer. I will try to confirm this (it's an old project of mine.) But You deserve a few +1 just for this clean and helpful answer! – Ofir Hadad Nov 24 '14 at 15:19
  • Hey Peter. I've followed this code and gotten the pointers from NP_GetEntryPoints. How do I go about calling my plugin functions though? – Tsury Mar 23 '16 at 12:17
  • @Tsury: Maybe [this SO question](http://stackoverflow.com/questions/2470487) might help you on. – Peter Ivan Mar 23 '16 at 12:40