我编写.net扩展名,可以加载到某些非托管应用程序的不同版本中。
下面我导入了some_func_v01
,some_func_v02
和some_func_v03
函数:
[DllImport("some_library_v1.0.dll", CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Unicode, EntryPoint = "func_name")]
extern static private void some_func_v01(string msg);
[DllImport("some_library_v2.0.dll", CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Unicode, EntryPoint = "func_name")]
extern static private void some_func_v02(string msg);
[DllImport("some_library_v3.0.dll", CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Unicode, EntryPoint = "func_name")]
extern static private void some_func_v03(string msg);
...
public void some_func(string msg)
{
switch (Application.Version.Major)
{
case 1: some_func_v01(msg); break;
case 2: some_func_v02(msg); break;
case 3: some_func_v03(msg); break;
}
}
some_library
库是目标应用程序的一部分,与应用程序具有相同的版本。
问题是,当出现新版本的应用程序时,我将编辑扩展程序的代码。我想根据应用程序版本动态生成代码。例如,对于应用程序版本1:
[DllImport("some_library_v1.0.dll", CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Unicode, EntryPoint = "func_name")]
extern static private void some_func(string msg);
我可以通过PowerShell托管使用,但可能更简单的方式存在...我不想创建PowerShell托管只是为了执行此任务。
存在这种简单的方法吗?
答案 0 :(得分:1)
我认为最好的解决方案是动态加载DLL。
使用WINAPI LoadLibrary和GetProcAddress获取该函数的地址。然后使用Marshal.GetDelegateForFunctionPointer获取.net委托。
示例:
//skipping WINAPI native definitions
//you need to define delegate type:
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
delegate void MyFuncType(string msg);
//how to get delegate object:
var library = LoadLibrary(libraryNameChosenAtRuntime);
var funcPtr = GetProcAddress(library, funcName);
var func = Marshal.GetDelegateForFunctionPointer<MyFuncType>(funcPtr);
// now you can use func as delegate
// you can store this delegate object somewhere and reuse.
func("msg");
答案 1 :(得分:0)
由于您知道外部应用程序的版本,因此您也知道其目录,因此也知道外部应用程序目录中某处的外部dll的位置。您要忽略的是dll的后缀名称(示例中给出的版本v_1部分)。我相信在每个外部应用程序版本中只有一个版本的dll。
如果我的假设是正确的那么你就可以实现这一切: