C#调用DLL时出现的错误(个人总结向)

您所在的位置:网站首页 c语言中找不到指定文件 C#调用DLL时出现的错误(个人总结向)

C#调用DLL时出现的错误(个人总结向)

2024-05-24 15:20| 来源: 网络整理| 查看: 265

C#调用DLL时出现的错误 前言1.环境配置问题1.1 无法加载*.dll,找不到指定的模块 2.DLL程序问题2.1 无法在dll中找到入口点2.2 在C#中捕捉DLL中函数异常2.3 Invalid address specified to RtlValidateHeap2.4 DLL编译 3.C#调用问题3.1 尝试读取或写入受保护的内存3.2 C# 调用dll出现托管问题3.3 参数不一致3.4 调用带传出数组函数 4.其他4.1 warning C4819: 该文件包含不能在当前代码页中表示的字符4.2 C++ error LNK2019: 无法解析的外部符号 WinMain

前言

在做实验室的工作中,出现了很多次C#调用DLL的错误,做下总结. 由于是个人向,解决方案难免缺乏鲁棒性,仅供参考,并不全面

保险的做法:编译的DLL放到项目下和System里,都放

1.环境配置问题 1.1 无法加载*.dll,找不到指定的模块

0.一般会在更换新电脑时出现该问题

1.用Dependency Walker 2.2或其他dll查看器打开*.dll 2.查看该电脑缺失(显示红色的)的*.dll的依赖库并下载,比如dll中调用了CGAL库,新电脑上缺失相关依赖库,则需要下载如下dll在这里插入图片描述

3.把*.dll以及依赖库放到C://Windows/System32(x64)或C://Windows/SysWow64(x86)里 4.最好重启下

2.DLL程序问题 2.1 无法在dll中找到入口点

示例: 在这里插入图片描述 规范DLL函数前缀 一般来说前缀为:extern “C” _declspec(dllexport) 更详细的可以参考 EntryPointNotFoundException

2.2 在C#中捕捉DLL中函数异常

1.app.config 添加:

2.函数前加 [HandleProcessCorruptedStateExceptions]

2.3 Invalid address specified to RtlValidateHeap

在这里插入图片描述 重复使用同一stringstream时,应该使用str()初始化

2.4 DLL编译

一定要用Release,Debug太慢了!

3.C#调用问题 3.1 尝试读取或写入受保护的内存

在这里插入图片描述 传入的数组长度开的太小了

3.2 C# 调用dll出现托管问题

在这里插入图片描述 DLLImport后面加入 CallingConvention = CallingConvention.Cdecl

3.3 参数不一致

例如对于dll中的函数 extern “C” _declspec(dllexport) int add(int a,int b) { return a+b; } 以及C#中的函数 [DllImport("*…dll")] public static extern int add(long a,long b) 调用add(1,2),返回1

3.4 调用带传出数组函数

带传出数组: C++不能直接传出数组,只传出数组指针,

void __declspec(dllexport) test(const int M, const int n[], int *N) { }

对应的C#代码:

[DllImport("*.dll")] public static extern void test(int M, int[] n, [MarshalAs(UnmanagedType.LPArray,SizeParamIndex=1)] int[] N); 4.其他 4.1 warning C4819: 该文件包含不能在当前代码页中表示的字符

Visual Studio 2017 出现warning C4819: 该文件包含不能在当前代码页中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失

解决方案: 1.修改字符编码格式 Visual Studio提供高级保存选项功能,它能指定特定代码文件的编码规范和行尾所使用的换行符。在Visual Studio 2017中,该命令没有默认显示在“文件”菜单中。用户需要手工设置,才能显示该命令。操作方法如下:

(1)单击“工具”|“自定义”命令,弹出“自定义”对话框。 (2)单击“命令”标签,进入“命令”选项卡。 (3)在“菜单栏”下拉列表中,选择“文件”选项。 (4)单击“添加命令”按钮,弹出“添加命令”对话框。 (5)在“类别”列表中,选择“文件”选项;在“命令”列表中,选择“高级保存选项”选项。 (6)单击“确定”按钮,关闭“添加命令”对话框。 (7)选中“控件”列表中的“高级保存选项”选项,单击“上移”或者“下移”按钮,调整该命令的位置。 (8)单击“关闭”按钮,完成“高级保存选项”命令的添加操作。 (9)打开“文件”菜单下的“高级保存选项”,设置编码为ASCII,关闭,然后再设置为unicode(utf-8)

4.2 C++ error LNK2019: 无法解析的外部符号 WinMain

临时将DLL修改为控制台输出时,报错

一,问题描述 MSVCRTD.lib(exe_winmain.obj) : error LNK2019: 无法解析的外部符号 WinMain,该符号在函数 “int __cdecl invoke_main(void)” (?invoke_main@@YAHXZ) 中被引用 CamShift.exe : fatal error LNK1120: 1 个无法解析的外部命令

error LNK2001: unresolved external symbol _WinMain debug/main.exe:fatal error LNK 1120:1 unresolved externals error executing link.exe;

二,原因及解决办法 产生这个问题的真正原因是c语言运行时找不到适当的程序入口函数. 一般情况下,如果是windows程序,那么WinMain是入口函数,在VS2017中新建项目为“win32项目” 如果是dos控制台程序,那么main是入口函数,在VS2017中新建项目为“win32控制台应用程序”

而如果入口函数指定不当,很显然c语言运行时找不到配合函数,它就会报告错误。

修改设置适应你的需求

如果是windows程序:

1.菜单中选择 Project->Properties, 弹出Property Pages窗口

2.在左边栏中依次选择:Configuration Properties -> C/C++ -> Preprocessor,然后在右边栏的Preprocessor Definitions对应的项中删除_CONSOLE, 添加_WINDOWS.

3.在左边栏中依次选择:Configuration Properties->Linker->System,然后在右边栏的SubSystem对应的项改为Windows(/SUBSYSTEM:WINDOWS)

如果是控制台程序:

1.菜单中选择 Project->Properties, 弹出Property Pages窗口

2.在左边栏中依次选择:Configuration Properties -> C/C++ -> Preprocessor,然后在右边栏的Preprocessor Definitions对应的项中删除_WINDOWS, 添加_CONSOLE.

3.在左边栏中依次选择:Configuration Properties->Linker->System,然后在右边栏的SubSystem对应的项改为CONSOLE(/SUBSYSTEM:CONSOLE)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3