2010-12-12 72 views
0

我需要建立一个软件,将读取XML里会有类似这样的标记:与其他语言互操作?

<Values type="MyParser.Parser" assembly="parser.dll" /> 

通过反射做起来很简单,但我需要找到一种方法,把任何类型的Ø语言,我的意思是,如果方法是用C编写的,如果它是用C语言编写的程序集,它也需要被调用。

我只能通过生成一个“exe”并将参数作为“命令行”发送并获取程序输出来考虑。

我不知道这是否是最好的方式。这是“安全”吗?还有另一种方法吗? C#能否从另一个程序集调用方法(使用另一种语言)?

On this page it says有关“您还可以与其他语言跨平台进行互操作”,但我不知道它的真正含义。

+1

程序集不是用C写的.exe或dll可能是,但它们不是程序集。 – erikkallen 2010-12-12 16:58:32

回答

1

你实际上只声明你想读取DLL文件,而不是你想要做的值。我假设你想实例化一个类型并为其调用一些方法。

这应该是非常容易的,如果它是一个托管DLL通过加载程序集,使用Type.GetType,然后Activator.CreateInstance。你应该为你想实例化的类型定义一个接口,这样你就可以得到一个很好的强类型对象来处理。如果你不能这样做,最好的选择可能是声明创建的实例dynamic,然后调用你想要的方法,让DLR做它的魔法。

现在事情变得更复杂,如果它是非托管代码。 C和其他过程语言不会有可以实例化和调用方法的类型的概念;所以你不能使用实例化对象的相同抽象。您需要区分托管代码和非托管代码。

C#有DllImport这是你通常用来调用非托管代码。这不是动态的,所以如果你事先不知道库和过程的名字,那么你就不能使用它。

你将能够创建一个解决方案,使用DllImport调用Win32本机方法LoadLibraryEx(加载DLL),然后GetProcAddress获取指向您要调用的函数的指针。然后,您可以使用Marshal.GetDelegateForFunctionPointer获取可以调用的C#委托。完成使用非托管库后,请不要忘记拨打FreeLibrary

0

这很大程度上取决于您尝试与之进行互操作。如果你想从另一个.NET程序集调用一个方法,那么你可以简单地引用它(它写的内容并不重要)。

我不认为可以通过COM调用任意方法,但可以声明每种可能的方法(与相关的Interop属性),然后选择一个您需要使用的依赖于配置值的方法。

如果外部程序集既不是.NET也不是COM,那么就没有办法直接调用它的方法。

您可以构建解决方案的最具互操作性的方式是使用Web服务调用。

0

经典的互操作源如下:

[System.Runtime.InteropServices.DllImport("opengl32.dll", EntryPoint = "glActiveTexture", ExactSpelling = true)] 
internal extern static void glActiveTexture(int texture); 

换言之,静态例程glActiveTexture在应用路径发现open32.dll二进制被发现,与签名(入口点)glActiveTexture。

有时候事情并不那么容易。例如:

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

你可以注意到参数之前[OUT]。该参数属性用于指示例程glGetActiveUniform将输出这些变量的数据,因为它们实际上是该函数写入的指针。

这是用于将互操作编组,这意味着,在进出外部例程参数的运行时副本(即:所述[OUT]属性指示可变复制出来一旦例程作为退出)。

上面的代码是由我的应用程序生成的,具有函数规范(在本例中为OpenGL)。我见过类似的代码生成器,它需要一个C头文件。

据我所知,你想实现这个dinamically,在运行时加载二进制文件。那么......我会是一个艰巨的任务,因为必须有一种方法来为每个库使用伴随配置来创建这些委托,但实际上我不知道这对任何语言都是可能的。

0

您可以使用p-invoke来执行从dll导出的C函数。