我是靠谱客的博主 无情舞蹈,最近开发中收集的这篇文章主要介绍C#调用C/C++动态链接库笔记(一)C#调用DLLC指针在C#中的移植数据类型移植堆栈不对称解决办法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

主要就以C#中dll调用,C的数据类型移植,C的指针在C#中如何实现,还有很难受的指针函数(这个作者搞了好久),还有一个是结构体在C#中的实现,最后是结构体中联合体在C#中如何调用(这个也很难受)。因为作者是小白,所以这篇文章讲的不会很深入,就以这前天调用库函数遇到的问题跟大家分享一下,有好多地方也是不求甚解,但最终调用是成功了。

C#调用DLL

[DllImport("fun_ptr.dll", EntryPoint = "CallFromDll"]
public static extern void CallFromDll(IntPtr fun);
  • 1
  • 2

这个调用很easy,输入这两句代码,就可以吧dll中的函数callformdll拿出来用了。需要做的准备就是把封装好的dll放到c#的…binDebug目录下就可以了,可惜作者要调用的函数有点复杂,是涉及到指针传值的。

C指针在C#中的移植

在C中的指针,例如比较常用的char*指向一条字符串,在C中一般依靠指针去传递,那么在C#中如何获取呢?(不要问为什么要用这个举列子,恰好做到这个罢了),给个例子自己看:
这是在dll头文件中的函数声明:

#ifdef _WIN32
#   ifdef DEVSDK2_EXPORTS
#       define DEVSDK2_API __declspec(dllexport)
#   else
#       define DEVSDK2_API 
#   endif
#else
#   define DEVSDK2_API __attribute__ ((visibility("default")))
#endif
DEVSDK2_API const char* checkLock();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

然后在C#中用IntPtr去提取,接着在转化成字符串,:

		[DllImport("DevSDK2.dll", EntryPoint = "checkLock")]
       	public static extern IntPtr checkLock();
        private void button1_Click(object sender, EventArgs e)
        {
            IntPtr str = checkLock();
            string ss = Marshal.PtrToStringAnsi(str);
            richTextBox1.Text = "***到期时间:"+ss;
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

数据类型移植

OK,其实C/C++中还有许多数据类型的定义有着区别,作者整理了下,
这是C语言中常用的数据类型定义:

typedef unsigned char   uint8_t;     			//无符号8位数     byte
typedef signed   char   int8_t;      			//有符号8位数	sbyte
typedef unsigned int    uint16_t;  			    //无符号16位数	UInt16
typedef signed   int    int16_t;    		    //有符号16位数	short
typedef unsigned long   uint32_t;   		    //无符号32位数	UInt32
typedef unsigned long long  uint64_t;           //无符号64位数   UInt64
typedef signed   long   int32_t;                //有符号32位数	int
typedef float           float32;                //单精度浮点数	float
typedef double          float64;                //双精度浮点数	double
typedef int bool;																
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

堆栈不对称解决办法

好吧尽管这么做了之后还有出现堆栈不对称的问题,比如:这是由于在调用时,两边的 数据不一致造成的。

在这里插入图片描述


解决方法有两种:
一:如果你可以修改dll源代码,那么恭喜你,你只需要做以下三步
1.在每个函数定义的时候定义成这个样子:

_LIBAPI void  __stdcall CallFromDll(X x);
  • 1

2.接着去C的导出目录,用文本的方式打开里面一个xxx.def文件,里面是dll函数的导出名字,会看到原本的:

EXPORTS
CallFromDll @1
  • 1
  • 2

变成了:

 EXPORTS
    CallFromDll@4 @1
  • 1
  • 2

3:.所以我们也灵活的将C#中的 [DllImport("fun_ptr.dll", EntryPoint = "CallFromDll"]修改为 [DllImport("fun_ptr.dll", EntryPoint = "CallFromDll@4"]就完成了

然而很遗憾,dll库文件是别人给的,还不写__stdcall,那我就只能修改C#的代码了,经过作者重重测试,发现在调用时下面增加字段,可以避免报错

        [DllImport("fun_ptr.dll", EntryPoint = "CallFromDll",CallingConvention =CallingConvention.Cdecl), ]
        public static extern void CallFromDll(IntPtr fun);
  • 1
  • 2

基本实现了C数据类型到C#中的移植过程。未完待续、、、

 

最后

以上就是无情舞蹈为你收集整理的C#调用C/C++动态链接库笔记(一)C#调用DLLC指针在C#中的移植数据类型移植堆栈不对称解决办法的全部内容,希望文章能够帮你解决C#调用C/C++动态链接库笔记(一)C#调用DLLC指针在C#中的移植数据类型移植堆栈不对称解决办法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(28)

评论列表共有 0 条评论

立即
投稿
返回
顶部