views:

95

answers:

3

Question: Is it possible to write a C# dll that can be pinvoked ?

I want to write a replacement library for the WinAPI calls WritePrivateProfileString etc. for reading and writing ini files.

Is it possible to export a function, e.g. 'WritePrivateProfileString', implemented in C# so one can pinvoke the dll with DllImport ?

I want to replace the native dll with a managed dll, so the managed dll gets called by the pinvoke call (instead of the native dll, when the managed dll is in the bin directory).

+7  A: 

Contrary to popular belief, this is possible. (note that you'll need to modify the calling application to import from your DLL)
See here.

However, in your case, it's not necessarily a good idea.
Why don't you change the extern declarations to normal methods that call your replacements?

SLaks
Doesn't have to be as dumb as it may read like. It could be that he wants to change the way another app reads INI files. And maybe he doesn't want to use a native language to do just that.
Robert Giesecke
@Robert: The question is talking about C#. He'll need to modify the calling application no matter what.
SLaks
Perhaps not, would this make it possible? http://msdn.microsoft.com/en-us/library/ms682586%28VS.85%29.aspx
Ani
@Ani: Are you sure that applies to system DLLs (which are already loaded)?
SLaks
@SLaks: I'm not sure either way, to be honest.
Ani
@Robert Giesecke: Exactly, I want to replace that kernel32.dll functionality on Linux, for a program where I don't have the source to. I want to write it in C#, because that way I don't get a native dependency (e.g. different versions of Linux/Unic/Mac). On Windows, it doesn't matter which dll is called. Of course, if that's not possible I can always write a native dll, but then I get that native libc + version dependency.
Quandary
@Quandary: I don't know if that's possible. For one thing, your DLL would need to implement _every_ function in `kernel32.dll`.
SLaks
@SLaks: No, only those used by the program's pInvokes, which is WritePrivateProfileString, etc., and not every function in kernel32.dll...
Quandary
@Quandary: And those used by .Net's P/Invokes (which may be fewer on Mono, but would be a very large number in Microsoft's CLR)
SLaks
+1  A: 

This is not easy, but it can be done with the use of a few “hacks”

However COM may be a better option for you, as it is easy to export a com object from C# and to use com objects from VB6. Then change the extern declarations to normal methods that call you’re your com objects.

Ian Ringrose
Read the question. He's not talking about VB6.
SLaks
The question was originally tagged with VB.net, not sure why though. I removed that tag.
emddudley
Little offtopic but which part was not easy?
Robert Giesecke
@Ian Ringrose: That's not necessary and beside the point. I need it to add windows API functionality to Linux, and COM doesn't work on Linux.
Quandary
A: 

Try using Mono Cecil to change the third-party program's extern methods to methods that call your DLL (without P/Invoke).

Reflector will help here.

SLaks