Interoperate with other languages?
I need to build a software that will read a XML where there will be开发者_如何学运维 a tag like:
<Values type="MyParser.Parser" assembly="parser.dll" />
Doing it by reflection is pretty simple, but I need to find a way to put any kind o language, I mean, if the method was written in C, if it is an assembly written in C, it needs to be called as well.
I can only think on doing it by generating an "exe" and send parameters as "command line" and getting the program output.
I wonder if it is the best way of doing it. Is this "safe"? Is there another way of doing it? Can C# call methods from another assembly (in another language)?
On this page it says something about "You can also interoperate with other languages, across platforms", but I don't know what it means really.
You actually only state that you want to read the DLL file, not what you want to do with the value. I'll assume you want to instantiate a type and call some method on it for my answer.
This should be pretty easy if it's a managed DLL by loading the assembly, using Type.GetType, then Activator.CreateInstance. You should define an interface for the type you want to instantiate, so you can get a nice strongly typed object to work with. If you can't do that the best option will probably be to declare the instance created dynamic
, and then just call the method you want and let the DLR do it's magic.
Now things get trickier if it's unmanaged code. C and other procedural languages won't have the concept of a type you can instantiate and call methods on; so you can't use the same abstraction of instantiating an object. You will need to differentiate between managed and unmanaged code.
C# has DllImport which is what you would normally use to call into unmanaged code. It's not dynamic though, so you can't use that if you don't know the library and procedure names beforehand.
You would be able to create a solution using DllImport to call into the Win32 native methods LoadLibraryEx (to load a DLL), then GetProcAddress to get a pointer to the function you want to call. Then you can use Marshal.GetDelegateForFunctionPointer
to get a C# delegate that you can call. When finished using the unmanaged library, don't forget to call FreeLibrary.
It very much depends what you're trying to interoperate with. If you want to call a method from another .NET assembly then you can simply reference it (it doesn't matter what it was written in).
I don't think it'll be possible to call an arbitrary method via COM but you could declare every possible method (with the relevant Interop attributes) and then select the one you need to use dependant on the config value.
If the external assembly is neither .NET nor COM then there is no way to directly invoke its methods.
The most interoperable way you can architect a solution would be to use web service calls.
The classic interop source is the following:
[System.Runtime.InteropServices.DllImport("opengl32.dll", EntryPoint = "glActiveTexture", ExactSpelling = true)]
internal extern static void glActiveTexture(int texture);
In other words, the static routine glActiveTexture is found in the open32.dll binary found in the application path, with the signature (EntryPoint) glActiveTexture.
Sometime the things are not so easy. For example:
[System.Runtime.InteropServices.DllImport("opengl32.dll", EntryPoint = "glGetActiveUniform", ExactSpelling = true)]
internal extern static unsafe void glGetActiveUniform(uint program, uint index, Int32 bufSize, [Out]Int32 length, [Out]int size, [Out]int type, [Out]StringBuilder name);
You can note the [Out] before the parameter. That parameter attribute is used to indicate that the routine glGetActiveUniform will output data on those variables, since they actually are pointer which the function writes.
This is for introducing the interop marshalling, which means that the runtime copy in and out the external routine parameters (i.e.: the [Out] attributes indicates to copy out the variable once the routine as exited).
The code above was generated by my application, having the function specification (in this case OpenGL). I've seen similar code generators which takes a C header.
As I can understand, you want implement this dinamically, loading binaries at runtime. Well... I would be an hard task, since there must be a way to create those delegates using a companion configuration for each library, but actually I don't know whether this is possible for any language.
You can use p-invoke to execute C functions exported from a dll.
精彩评论