《C# 语言入门 - 学习笔记 - C#调C/C++(Dll)方法总结》

文章目录前言一、基础知识1. 结构体对齐1. 内存对齐2. 调用约定3. C#与C/C++类型对应关系2. 创建并调用动态链接库3. Dllimport常用参数二、实例调用1. C#与Dll链接库的数据交换1. 基本数据类型2. 数组(引用传递)3. 结构体2. C++回调C#前言视频资源:B站:C#与C/C++动态链接库本篇对C#与C/C++动态链接库做一个小结。一、基础知识1. 结构体对齐1. 内存对齐定义: 计算机系统对基本数据类型合法地址做出一些限制,要求某些类型地址必须是某
摘要由CSDN通过智能技术生成


前言

一、基础知识

1. 结构体对齐

1. 内存对齐

  • 定义: 计算机系统对基本数据类型合法地址做出一些限制,要求某些类型地址必须是某个值K的倍数
  • 目的: 简化处理器喝存储器系统之间的接口硬件设计,方便存储器操作读取或写入;
  • 规则:
  1. 结构体的数据成员,第一个成员的偏移量为0,后面每个数据成员存储的起始位置要从自己大小的整数倍开始;
  2. 子结构体中的第一个成员偏移量应当是子结构体中最大成员的整数倍
  3. 结构体总大小必须是其内部最大成员的整数倍
#include <iostream>
#define FIELDOFFSET(TYPE,MEMBER)(int)(&(((TYPE*)0)->MEMBER))
//定义判断字符的字节方法

#pragma pack(push)	//入栈 (先进后出)
#pragma pack(1)	//设置字节对齐方式,1字节对齐(一个接一个,紧挨着)
struct Info 
{
   
	char username[10];   //24-34
	double userdata;	 //40-48(8的倍数)
};	
#pragma pack(pop)	//出栈

struct Frame			 
{
   						 //字节:
	unsigned char id;	 //0-1
	int width;			 //4-8
	long long height;	 //8-16
	unsigned char* data; //16-20
	Info info;			 //24-
};
int main()
{
   
	int len = sizeof(Frame);//result:48
	int len2 = sizeof(Info);//result:24;	设置出入栈后字节为18
	int offset_width = FIELDOFFSET(Frame, width);//result:4;	FIELDOFFSET用来判断字符所占字节
	int offset_longlong = FIELDOFFSET(Frame, height); //result:8;
	return 0;
}
  • 查看结构体偏移量方法:#define FIELDOFFSET(TYPE,MEMBER)(int)(&(((TYPE*)0)->MEMBER))

2. 调用约定

  • _cdecl: C调用约定,参数从 右至左的方式入栈,函数本身不清理栈,由调用者负责,故,允许可变参数函数存在;
  • _stdcall: 标准调用约定,参数按照从 右至左的方式入栈,函数本身清理栈
    在这里插入图片描述

3. C#与C/C++类型对应关系

  • 说明:ubyte<—>char;byte<—>unsigned char
    在这里插入图片描述

2. 创建并调用动态链接库

  1. 新建文件夹,存放项目(src 源码文件夹)
    在这里插入图片描述
    在这里插入图片描述

  2. 创建C# 项目(.Framework)

  • 设置输出目录、目标平台(x64)
    在这里插入图片描述
  • 启用本地代码调试(方便调试跳转dll文件):
    在这里插入图片描述
  • 链接Dll示例:
    在这里插入图片描述
  1. 创建C++项目
  • 设置输出/调试目录
    在这里插入图片描述
  • 链接Dll示例:
    在这里插入图片描述
  1. 创建Dll动态链接库
  • 取消预编译头
    在这里插入图片描述

  • 输出目录
    在这里插入图片描述

  • 配置预编译、宏定义
    在这里插入图片描述
    在这里插入图片描述

  1. 配置项目依赖项
    在这里插入图片描述
  • 重新生成解决方案:
    在这里插入图片描述

3. Dllimport常用参数

在这里插入图片描述

二、实例调用

1. C#与Dll链接库的数据交换

  • C/C++基本数据字节:
    在这里插入图片描述

1. 基本数据类型

  • 值传递(C# ----> C/C++)
  1. Dll代码(.h / .cpp)
#pragma once
//预编译
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif // __cplusplus

//宏定义
#ifdef DLL_IMPORT
#define HEAD EXTERNC __declspec(dllimport)
#else
#define HEAD EXTERNC __declspec(dllexport)
#endif // DLL_IMPORT

#define CallingConvention _cdecl

//示例方法
HEAD void CallingConvention Test_BasicData(char d1,short d2,int d3,long long d4,float d5,double d6);
#include "Native.h"
#include <iostream>

HEAD void CallingConvention Test_BasicData(char d1, short d2, int d3, long long d4, float d5, double d6)
{
   
	d1, d2, d3, d4, d5, d6;
}
  1. C#代码
using System;
using System.Runtime.InteropServices;

namespace CallNativeDllCSharp
{
   
    class Program
    {
   
        [DllImport("NativeDll.dll",CallingConvention = CallingConvention.Cdecl)]
        public static extern void Test_BasicData(sbyte d1, short d2, int d3, long d4, float d5, double d6);
        static void Main(string
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值