[英]C# program call C# dll
我想用C#的exe動態加載C#或者C++構建的dll,C++的dll部分已經完成了,但是C#的dll還沒有完成,因為exe在C#的dll中找不到方法。
這是我的 C# dll 代碼,它將構建一個 CSharp.dll:
namespace NamespaceName
{
public class ClassName
{
static public double MethodName(string input)
{
Console.WriteLine(input);
Console.Read();
return 0;
}
}
}
這是我的 C# exe 代碼:
using System;
using System.Runtime.InteropServices;
namespace TestCall
{
class Program
{
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
static extern int LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);
[DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
static extern IntPtr GetProcAddress(int hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName);
[DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]
static extern bool FreeLibrary(int hModule);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate double MethodName(string a);
static void Main(string[] arg) //pass in string array
{
string DllName = "...Desktop//CSharp.dll"; //would be like: string DllName = ChooseWhatDllToCall();
string FuncName = "NamespaceName@ClassName@MethodName"; //would be like: string FuncName = ChooseWhatFuncToUse();
int hModule = LoadLibrary(DllName);
if (hModule == 0)
return;
IntPtr intPtr;
intPtr = GetProcAddress(hModule, FuncName);
if ((int)intPtr == 0)
{
FreeLibrary(hModule);
return;
}
MethodName run = (MethodName)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(MethodName));
string input = "just a string that will print by dll method";
double result = run(input);
FreeLibrary(hModule);
return;
}
}
}
如果我正在加載 Cpp.dll, if ((int)intPtr == 0)
將為假,加載 CSharp.dll 將為真,所以我猜我需要編輯string FuncName = "NamespaceName@ClassName@MethodName";
到別的東西。 我怎樣才能解決這個問題?
我現在回答我自己的問題,它可能不完美,但它有效,感謝您的評論建議。
using System;
using System.Runtime.InteropServices;
using System.Reflection;
namespace TestCall
{
class Program
{
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
static extern int LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);
[DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
static extern IntPtr GetProcAddress(int hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName);
[DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]
static extern bool FreeLibrary(int hModule);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate double MyMethod(string a);
static void Main(string[] arg)
{
string DllName = "...Desktop\\CSharp.dll"; //or Cpp.dll
string FuncName = "MyMethod";
string input = "Just A String";
int hModule = LoadLibrary(DllName); // you can build it dynamically
IntPtr intPtr = GetProcAddress(hModule, FuncName);
if ((int)intPtr!=0 && hModule != 0) //can I try this way?
{ // Yes!
MyMethod run = (MyMethod)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(MyMethod));
double result = run(input);
Console.WriteLine(result);
Console.Read();
FreeLibrary(hModule);
return;
}
else //No!
{
FreeLibrary(hModule);
//so I try other way
var DLL = Assembly.LoadFile(DllName);
foreach (Type type in DLL.GetExportedTypes())
{
var c = Activator.CreateInstance(type);
type.InvokeMember(FuncName, BindingFlags.InvokeMethod, null, c, new object[] { input });
}
return;
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.