c#调用c语言dll需要注意的地方

一、将C#工程和C的dll工程放在同一个解决方案下,这样就可以实现联动调试,直接从C#中进入C的dll函数里。注意:每次更改dll中的代码后都必须重新生成dll。另,C#与C中有几种变量类型不对应,注意声明时的区分。

语言 C# C
类型 long long long/__int64
byte/Byte unsigned char
char
wchar_t

UInt32 size_t

二、dll工程中头文件加入以下代码:

// 此代码为了方便头文件在dll工程和调用该dll的工程中重复利用
// 为了方便其他使用者,建议dll开发者定义TESTDLL宏
#ifdef  TESTDLL
#define DLLAPI _declspec(dllexport)
#else
#define DLLAPI _declspec(dllimport)
#endif

// 此代码为了保证使用C编译器编译代码,防止函数名出现其他后缀

#ifdef __cpluscplus
extern "C" {
#endif

// 插入所需导出的代码,例如:
int DLLAPI testdll();

#ifdef __cpluscplus
}
#endif
 

三、dll工程中源文件加入以下代码(注意:该代码应该出现于上述头文件之前):

#define TESTDLL

四、C#工程中,需要调用dll函数的文件中加入以下代码:

// 导入testdll函数
[DllImport(@"../../../Debug/testdll.dll", EntryPoint = "testdll", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]

extern static int testdll();

第一个参数是dll文件所在地址,由于该dll与C#工程在同一个解决方案中因此可以写成上述形式;

EntryPoint, 函数的名称,可以不写,下面一行有声明;

SetLastError, 指示方法是否保留 Win32"上一错误";

CharSet, dll中字符串的表达方式,通常使用Ansi或者Unicode;该设置会将C#中的字符自动转换为设置的方式,例如上述设置会将工程中的字符串转换为Ansi字符;

ExactSpelling,指示 EntryPoint 是否必须与指示的入口点的拼写完全匹配;

PreserveSig,指示方法的签名应当被保留还是被转换;

CallingConvention,调用惯例,通常C语言使用Cdecl方式CallingConvention,如果该值与dll中的调用方式不一致,通常会造成堆栈不平衡,导致PInvoke报错,该选项有如下几个值:

Cdecl 调用方清理堆栈。这使您能够调用具有 varargs 的函数(如 Printf),使之可用于接受可变数目的参数的方法。 
FastCall 不支持此调用约定。
StdCall 被调用方清理堆栈。这是使用平台 invoke 调用非托管函数的默认约定。 
ThisCall  第一个参数是 this 指针,它存储在寄存器 ECX 中。其他参数被推送到堆栈上。此调用约定用于对从非托管 DLL 导出的类调用方法。 
Winapi  此成员实际上不是调用约定,而是使用了默认平台调用约定。例如,在 Windows 上默认为 StdCall,在 Windows CE.NET 上默认为 Cdecl。 

以上就是c#调用c dll需要注意的地方的详细内容,更多关于c#调用c dll的资料请关注我们其它相关文章!

(0)

相关推荐

  • 关于C#调用C++dll传指针释放内存问题

    一.传入dll前,在C#中申请内存空间 c#里面的指针即 IntPtr 申请如下: IntPtr SrcImgData = Marshal.AllocHGlobal(length); 这种需要提前知道空间大小,否则无法确定空间大小,会导致dll内部处理时越界报错. c#里面申请空间了,那么c++里面一般就是在这些空间里面操作了,一般不会重新分配内存,那么就不需要加引用了. c++: uchar* SrcImg c#导入dll函数时申明: IntPtr SrcImg 那么内存释放自然也是由c#来进

  • vs2019 实现C#调用c++的dll两种方法

    1.托管与非托管的区别 链接地址(仅供参考) 除了链接中的,在实用角度出发: 非托管需要一个个声明引用,就很繁琐 但是托管(虽然麻烦)不用声明,只需要调好配置即可,还是比较方便的 为什么写这个博客,也是因为不同版本vs2017和vs2019有所区别,托管就容易踩坑,希望大家能看看,解决问题(我也很菜,大佬轻喷) 2.非托管类的实现 第一步:创建C++空项目(命名Caculate)添加一个类AddOperate .h代码部分: #pragma once extern "C" _decls

  • C#如何通过probing指定dll寻找文件夹详解

    前言 我们在很大的项目开发,会发现项目引用的 dll 会很多,我想要按照不同的功能,将不同的 dll 放在不同的文件夹 简单的方法是通过修改 App.config 文件指定文件夹,如将文件移动到 abc\12 的文件夹里面,可以在 App.config 添加代码 <?xml version="1.0" encoding="utf-8" ?> <configuration> <runtime> <assemblyBinding

  • C# [ImportDll()] 知识小结

    这周在做公司的一个C#项目中,要写一个webservice提供一个下载方法,之前公司有过,但是要整改,于是这种鸟屎摊子又交给了我,其中一个密文流的下载中要应用我们小组另一伙人用C++写的四个dll, 这些DLL是由我们自己编写的,非.NET 托管,这是一个麻烦事: 如果用 IDE往工程里add reference时,它会提示这几个dll是没有注册的,不是.NET托管的.好吧,顺便补充一下.NET托管和非托管. 具体官方术语是: 托管DLL就是能够在公共语言运行库(Common Language

  • C#调用易语言写的Dll文件方法

    本人是用易语言起步的,起初是为了兴趣,后来由于易语言被杀软误杀严重,连空白程序都杀,后来转到了学C#,随着学习的深入,接触越来越复杂的东西之后,发现有些功能没有用易语言来写方便,所以就想到用C#来调用易语言写的DLL,就和一般的Dll调用一样,没什么技术含量. 易语言中新建个Dll文件 C#中和一般的DLL一样调用 <p>using System; using System.Collections.Generic; using System.ComponentModel; using Syst

  • C#调用C++dll方法步骤

    C#调用C++dll的方法和步骤 其他分享涉及到的概念和方法对于像我这样比较菜的选手看起来比较费劲并且很难抓住重点,这里我总结了一段时间的研究成果供初学者救济之用,简单明了. 1.新建项目->Visual C++->Win32项目 MyDLL 注意:C++编写的dll一般是不能直接拿来C#调用,需要先新建个C++的工程把dll里的方法重新封装成可被C#外部调用的函数. 2.MyDLL.cpp里的代码如下: extern "C" _declspec(dllexport)int

  • C# 嵌入dll 的方法

    在很多时候我们在生成C#exe文件时,如果在工程里调用了dll文件时,那么如果不加以处理的话在生成的exe文件运行时需要连同这个dll一起转移,相比于一个单独干净的exe,这种形式总归让人不爽,那么有办法让生成的软件中直接就包含这个dll文件吗,这样就可以不用dll跟着exe走了,避免单独不能运行的情况. 答案是有的! 在工程项目目录下找到Resources.resx文件并点击,然后按下面操作,添加资源,将你要加入的dll添加进来. 操作完成后,就会在下面的内容框里看到你添加进来的dll. 然后

  • Qt程序中调用C#编写的dll(推荐)

    1.打开Visual Studio,新建一个C#的Class Library项目(这里选择的是.Net Framework 4),项目名为CSharpDll. 2.由于默认没有引入Forms等UI库,先在reference中添加引用System.Windows.Forms以便可以在测试中使用MessageBox等. 3.最终C#编写的dll的源代码如下图所示,命名空间为CSharpDll,公共类为CSharpClass. using System; using System.Collection

  • C#中托管DLL和非托管DLL的区别详解

    首先解释一下,托管DLL和非托管DLL的区别.狭义解释讲,托管DLL就在Dotnet环境生成的DLL文件.非托管DLL不是在Dotnet环境生成的DLL文件. 托管DLL文件,可以在Dotnet环境通过 "添加引用" 的方式,直接把托管DLL文件添加到项目中.然后通过 Using DLL命 名空间,来调用相应的DLL对象 .  非托管DLL文件,在Dotnet环境应用时,通过 DllImport 调用. C# 调用非托管DLL文件.DLL文件是用C语言编写的. 托管DLL就是能够在公共

  • C#调用Win32的API函数--User32.dll

    Win32的API函数是微软自己的东西,可以直接在C#中直接调用,在做WinForm时还是很有帮助的.有时候我们之直接调用Win32 的API,可以很高效的实现想要的效果. 代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; namespace WindowsAPI { class CSharp_

  • C#调用C类型dll入参为struct的问题详解

    前言 C# 可以通过 DllImport 的方式引用 C 类型的 dll.但很多 dll 的参数不会是简单的基础类型,而是结构体 struct .因此就需要在 C# 端定义同样的结构体类型,才能实现调用 C 类型 dll.这里例举几种不同的结构体情况,以及其对应的解决方案. 基础调用方式 对于一个结构体类型: typedef struct DATA { int nNumber; float fDecimal; }; 在 C# 端就需要定义为 [StructLayout(LayoutKind.Se

  • C#使用反射(Reflect)获取dll文件中的类型并调用方法

    使用反射(Reflect)获取dll文件中的类型并调用方法,具体内容如下 需引用:System.Reflection; 1. 使用反射(Reflect)获取dll文件中的类型并调用方法(入门案例) static void Main(string[] args) { //dll文件路径 string path = @"D:\VS2015Project\001\Computer\bin\Debug\computer.dll"; //加载dll文件 Assembly asm = Assemb

  • C# 添加对System.Configuration.dll文件的引用操作

    却被编译器提示说: 警告 1 "System.Configuration.ConfigurationSettings.AppSettings" 已过时: "This method is obsolete, it has been replaced by System.Configuration!System.Configuration.ConfigurationManager.AppSettings" 于是转而想找到那个ConfigurationManager类来使

  • VSCode调试C#程序及附缺失.dll文件的解决办法

    刚开始使用VScode,经过两天的折腾,初步解决了调试C#无法生成.dll文件的问题,现将我的过程叙述如下(使用到.Net Core+VScode+C#插件). 1.首先在D盘建立一个新的文件夹,我的文件名是C# file,如下: 2.然后打开VS code,通过file -> Add Folder to Workspace选项将刚才建立的新的文件夹加入到工作空间中,如下: 3.通过命令Ctrl+shift+y打开调试控制台(DEBUG CONSOLE),然后选择终端(TERMINAL),会看到

随机推荐