原因
今天遇到了一个加载dll出问题的情况,因为这个dll是cpp写的,而且是x86的,然后我一直用的x64来调用...
出现: System.BadImageFormatException:“试图加载格式不正确的程序。(异常来自HRESULT:Ox8007000B)”
dll的实现
c/cpp的dll是这样写的:
//第二个参数返回:第一个参数的数组两个数的和
//数组传参是靠第一个元素的指针,但是返回也返回了指针,这就考验对cpp和c#的理解了.
int_stdcall test(double* point, double* out)
{
out[0] = point[0]+ point[1];
}
cpp调用
让e大用cpp调用,结果没有出错...
int main(int argc, char* argu[])
{
typedef int(_stdcall* lpAddFun) (double*, double*); //宏定义函数指针类型
HINSTANCE hDll; //DLL句柄
lpAddFun addFun; //函数指针
hDll = LoadLibrary("TestAdd.dll");
int resu1t = 0;//将函数返回的值赋给它,这里先初始化
if (hDll != NULL)
{
addFun = (lpAddFun)GetProcAddress(hDll, "test");//用addFun取代dll库中的test函数
if (addFun != NULL)
{
double a1[] = { 10, 30 };
double a2[] = { 0 };
result = addFun(a1, a2);//这里是将数组作为参数传进去
printf("输出结果为%0.4lf
", a2[0]);
}
FreeLibrary(hDll);
}
systen("pause");
return 0;
}
csharp的实现
然后发现是x86的问题:
class Program
{
[DllImport("TestAdd.dll", EntryPoint = "test")]
public static extern int Add(double[] point, double[] outarr);
static void Main(string[] args)
{
double[] a1 = new double[2] { 10, 20 };
double[] a2 = new double[1];
Add(a1, a2);//否则这句就会报错
Console.WriteLine(a2[0].ToString());
Console.ReadLine();
}
}
一定要设置一下这里:
否则还会导致 Win32Api的LoadLibrary()返回空指针.
然后发现可以写得骚气一点.
class Program
{
[DllImport("TestAdd.dll", EntryPoint = "test")]
public static extern int Add(IntPtr point, IntPtr outarr);
//public static extern int DeAdd(double[] point, double[] outarr);
public static void AddInvoke()
{
double[] a1 = { 10, 20 };
IntPtr inp1 = Marshal.UnsafeAddrOfPinnedArrayElement(ary, 0);
double[] a2 = new double[1];
IntPtr inp2 = Marshal.UnsafeAddrOfPinnedArrayElement(aryb, 0);
Add(inp1, inp2);
MessageBox.Show(a2[0].ToString());
}
}
(完)