6

Attempting to build a C# NPAPI plugin I have found a tutorial which describes that your dll needs to implement a number of methods such as NP_GetEntryPoints , NP_Initialize and NPP_New along with a number of others.

However what I want to understand is if I can simply mirror these method names and construct equivalent datastructures as described in the article (like _NPPluginFuncs) in C# and everything will work?

Could someone please be kind enough to provide some guidance? Is it possible to build a NPAPI plugin in C# and if so what are the basic steps involved?

Maxim Gershkovich
  • 45,951
  • 44
  • 147
  • 243
  • 3
    I can't give you a detailed answer on NPAPI specifically, but in general, using C# to create a DLL with C-compatible exported functions is not possible. You could either 1) create a mixed-mode C++ DLL, or (likelier if you're more comfortable in C# than managed C++) 2) create a small native DLL containing your exports, which uses COM interop to delegate to a managed assembly written in C# and which contains the bulk of your functionality. – anton.burger Jul 05 '12 at 13:08
  • Now thats basically an answer. I assumed that in a worse case some type of interop would be possible (although didn't know enough about c++ to assume COM) but I also figured there would be an easier path for interop between C++ and C# – Maxim Gershkovich Jul 05 '12 at 13:15
  • P/Invoke is great, but interop in the other direction remains painful, I'm afraid :P – anton.burger Jul 05 '12 at 13:19
  • 1
    Interesting-looking project [here](https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports) which could make life a lot easier if you don't mind taking the dependency. – anton.burger Jul 05 '12 at 13:52
  • @shambulator: You should move those comments to an answer (NPAPI plugins are basically DLLs with a few required C-exports). – Georg Fritzsche Jul 06 '12 at 14:26
  • 1
    Is there away to split the bounty between these answers? Not sure which one to mark correct. Thank you both! – Maxim Gershkovich Jul 08 '12 at 06:53

2 Answers2

4

As stated in the documentation:

A NPAPI browser plugin is, at it’s core, simply a DLL with a few specific entry points

That means you need to export some function from a regular dll, that is done usually in C/C++. Unfortunately it is not possible to expose any entry point from a plain C# dll, but look at this answer, with some effort it appear to be possible to trick some export by some sort of post build tool.

In any case don't expect to pass too much complicated data structures from/to the plugin interfaces, it will be a pain. If you are interested in doing more research the keywork to use is "reverse P/Invoke", in analogy with direct P/Invoke that is calling regular dll from managed world.

The reason a C# dll can't expose directly "entry points" is that entry point are actually just some address inside the dll poiting to some assembly code immediately executable. C# dll are different kind of beast: they are just files containing IL that is compiled "Just In Time" and indeed such compilation is forced AFAIK with some OS tricks. This is the reason reverse P/Invoke is not starightforward at all.

Community
  • 1
  • 1
Felice Pollano
  • 32,832
  • 9
  • 75
  • 115
  • That's actually the exact statement that confused me "A NPAPI browser plugin is, at it’s core, simply a DLL with a few specific entry points" - My first thought was 'Great, so I can write this in C#' I guess I never really thought about how DLLs implements 'entry points' and have always assumed that the 'entry points' in C++ and C# would work the same. In retrospect a silly thought but I have never written a line of C++ – Maxim Gershkovich Jul 05 '12 at 13:32
  • Thank you, I appreciate the clarification. – Maxim Gershkovich Jul 08 '12 at 06:55
4

As Georg Fritzsche says in his comment:

NPAPI plugins are basically DLLs with a few required C-exports

and there is no built-in way to export functions (in the C-export sense) from an assembly written in C#.

Some of your options are:

  1. A mixed-mode C++ assembly which can export the functions directly. This could have implications for hosting the CLR in your plugin's host process.
  2. A small native DLL which hosts the exports, then uses COM interop to delegate to a C# assembly containing the plugin functionality. The "official" way to do so-called "reverse p/invoke".
  3. An intriguing project which post-processes your fully-managed assembly, turning static methods marked with a custom attribute into named function exports. (I have no affiliation with this project; I stumbled across it after I got to wondering whether anyone had improved on the COM interop way of doing things.)
anton.burger
  • 5,637
  • 32
  • 48