抛出问题

C#项目要采用第三方的方案实现某个功能,第三方提供了一个C++实现的库Dll库。然鹅,在实现的过程中遇到一系列的问题,最后都搞懂了,现分享下过程,主要问题总结如下:

1、System.DllNotFoundException 解决之路无法加载DLL“xxx.dll”:找不到指定的模块(异常来自HRESULT:0X8007007E)
2、未处理System.BadImageFormatException,试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)
3、System.EntryPointNotFoundException:Unable to find an entry point named
4、C# 和C++ 数据结构映射(结构体指针)

痛苦的解决过程

① 右键添加引用报如下错误:请确保此文件可访问并且是一个有效的程序集或COM组件

在这里插入图片描述

② 按网上说的 regsvr32 dll 还是不通

③ 既然此法不通换个思路,得用DllImport代码导入方式

DllImport代码举例如下(注意int* 用IntPtr ,char* 用string替换)

[DllImport("xxxxxxxx.dll"]
   public static extern IntPtr XXXXOpen(string xxxx01, string xxxx02){……};

④ 然鹅,又报错误 无法加载 DLL“xxxx.dll”: 找不到指定的模块

继续度娘,发现有可能是缺少依赖项的情况。下载使用depends.exe查看xxxx.dll的依赖项,分析看,果不其然缺了不少依赖库啊,下载缺失的依赖项到Debug目录下,解决

⑤然鹅,又报错误 System.BadImageFormatException
这个是因为,程序中引用外部dll文件的目标平台的版本x86和x64不一致引起的

⑤然鹅,又报错误 System.EntryPointNotFoundException
原因:在C++函数声明时要将 extern “C” 添加在 DLL 函数声明之前 。
如果不加的话,C++编译为dll之后,函数名会发生变化,会多了一些符如号?@@等,有些参数顺序还会发生变化。可以用DllAnalyzer工具查看dll的输出函数名,发现输出的函数名有所变化,多了@xxx和一些别的奇怪的字符,实际上是因为C++重载机制造成的,使用使用extern "C"关键字即可或者直接把那一长串拷贝过去可以解决!

[DllImport("a.dll",EntryPoint="?F@@YAHXZ")]  
public extern static int F();

⑥ 至于C# 和C++ 数据结构映射(结构体指针),参考如下

PS:后面找到有个工具可以自己生成 ===>【CLRInsideOut】C#调用C++DLL结构体或函数声明代码生成工具

struct A{
	double a[20];
};

struct B{
	double b[20];
	int c[10];
};	

extern “C” _declspec(dllexport) int abc(
	char* filePath, 
	A* input, 
	B* output,
	int flag 
);

[StructLayout(LayoutKind.Sequential)]
public struct A
{
	[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20, ArraySubType = UnmanagedType.R8)]
	public double[] a;
}

[StructLayout(LayoutKind.Sequential)]
public struct B
{
	[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20, ArraySubType = UnmanagedType.R8)]
	public double[] b;

	[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20, ArraySubType = UnmanagedType.I4)]
	public int[] c;
}

[DllImport("xxx.dll", EntryPoint = "abc", CallingConvention = CallingConvention.Cdecl)]
public static extern int abc(
	string filePath, 
	ref A input, 
	out B output,
	int flag 
	);

总结

如上就是我遇到的坑及解决方法,希望给有需要的同学有所帮助!!!

参考

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐