返回顶部
首页 > 资讯 > 精选 >C#中调用C类型dll入参为struct的问题分析
  • 588
分享到

C#中调用C类型dll入参为struct的问题分析

2023-06-14 06:06:56 588人浏览 独家记忆
摘要

这篇文章将为大家详细讲解有关C#中调用C类型dll入参为struct的问题分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前言C# 可以通过 DllImport 的方式引用 C 类型的 dll。但很多

这篇文章将为大家详细讲解有关C#中调用C类型dll入参为struct的问题分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

前言

C# 可以通过 DllImport 的方式引用 C 类型的 dll。但很多 dll 的参数不会是简单的基础类型,而是结构体 struct 。因此就需要在 C# 端定义同样的结构体类型,才能实现调用 C 类型 dll。这里例举几种不同的结构体情况,以及其对应的解决方案。

基础调用方式

对于一个结构体类型:

typedef struct DATA{  int nNumber;  float fDecimal;};

在 C# 端就需要定义为

[StructLayout(LayoutKind.Sequential)]public struct DATA{  public int nNumber;  public float fDecimal;}

包含字符数组

对于一个包含字符数组的结构体类型:

typedef struct DATA{  int nNumber;  float fDecimal;  char szString[256];};

在 C# 端就需要使用 Marshal 设置数据空间大小,同时最好定义一个初始化函数与 get 的定义

[StructLayout(LayoutKind.Sequential)]public struct DATA{  void alloc() {    szString = new char[256];  }  string sString {    get {      int nLength = 256;      string sData = "";      for (int i = 0; i < nLength; i++)      {        if (szData[i] == '\0') break;        sData += szData[i];      }      return sData;    }  }  public int nNumber;  public float fDecimal;  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]  char[] szString;}

包含字符二维数组

对于一个包含字符二维数组的结构体类型:

typedef struct DATA{  int nNumber;  float fDecimal;  char szString[6][256];};

在 C# 端同样需要使用 Marshal 设置数据空间大小,需要将两个 Size 相乘,并定义一个初始化函数。同时在做一个 get 的定义。

[StructLayout(LayoutKind.Sequential)]public struct DATA{  void alloc() {    szString = new char[256 * 6];  }  public string[] sStrings  {    get {      int nSize = 6, nLength = 256;      string[] sDatas = new string[nSize];      for (int i = 0; i < nSize; i++)      {        for (int j = 0; j < nLength; j++)        {          if (szData[i * nLength + j] == '\0') break;          sData += szData[i * nLength + i];        }        sDatas[i] = sData;      }      return sDatas;    }  }  public int nNumber;  public float fDecimal;  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256 * 6)]  char[] szStrings;}

dll 入参为结构体数组

若有一个这样的 C dll 函数定义:

void FnCall(DATA* datas);// 调用方式DATA datas[10];fnCall(datas);

那么,在 C# 中要实现等价调用:

// 首先 Import 函数[DllImport("Module.dll")]public static extern void FnCall(IntPtr pInfo); // 注意入参要定义为指针// 再定义定义结构体数组int nCount = 10;DATA datas = new DATA[nCount];// 再分配内存空间int nSize = Marshal.SizeOf(typeof(DEVICE_INFO));IntPtr Dataptr = Marshal.AllocHGlobal(nSize * nCount);// 调用函数FnCall(Dataptr);// 复制数据到结构体中for (int i = 0; i < nCount; i++){  IntPtr ptr = (IntPtr)((UInt32)Dataptr + i * size);  datas[i] = (DEVICE_INFO)Marshal.PtrToStructure(ptr, typeof(DEVICE_INFO));}// 释放内存空间Marshal.FreeHGlobal(Dataptr);

另外,如果你要调用的 dll 是非 C 类型 dll,而是 c++ Class。那么我们就可以将其再包装一层,转换为 C 类型 dll。

例如:

class Example {public: int MethodCall();};

那么就可以编写 C 类型的 dll。

extern "C" {  Example* Example_New() {     return new Example();   }  int Example_MethodCall(Example* p) {     return p->MethodCall();   }  void Example_Delete(Example* p) {     delete p;   }}

C# 那边就这样导入

[DllImport("Module.dll")]public static extern IntPtr Example_Create();[DllImport("Module.dll")]public static extern int Example_MethodCall(IntPtr value);[DllImport("Module.dll")]public static extern void Example_Delete(IntPtr value);// 调用方式IntPtr p = Example_Create();Example_MethodCall(p);Example_Delete(p);

关于“C#中调用C类型dll入参为struct的问题分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

--结束END--

本文标题: C#中调用C类型dll入参为struct的问题分析

本文链接: https://lsjlt.com/news/268797.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C#中调用C类型dll入参为struct的问题分析
    这篇文章将为大家详细讲解有关C#中调用C类型dll入参为struct的问题分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前言C# 可以通过 DllImport 的方式引用 C 类型的 dll。但很多 ...
    99+
    2023-06-14
  • C#调用C类型dll入参为struct的问题详解
    前言 C# 可以通过 DllImport 的方式引用 C 类型的 dll。但很多 dll 的参数不会是简单的基础类型,而是结构体 struct 。因此就需要在 C# 端定义同样的结构...
    99+
    2024-04-02
  • c# Struct的一些问题分析
    目录与类的区别:Struct的理论看过好一些,可是工作上基本没有应用过,Class倒处处都有。难道Struct就没有什么使用价值吗?搜了一下如何在类和结构中做出选择? Ϩ...
    99+
    2024-04-02
  • C#调用Windows API之参数类型的示例分析
    小编给大家分享一下C#调用Windows API之参数类型的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!C#调用Windows API之参数类型1、数值...
    99+
    2023-06-18
  • 关于python调用c++动态库dll时的参数传递问题
    目录stringcv::Matstring C++生成dll代码: #include <iostream> extern "C" __declspec(dllexport...
    99+
    2024-04-02
  • 关于C# 调用Dll 传递字符串指针参数的问题
    最近用c#写一个小软件,要调用VC写的dll,传递参数给dll,由于是非托管代码,所以调用起来有点麻烦,要把参数转换成非托管代码的指针参数,然后再传递给dllview plainco...
    99+
    2024-04-02
  • 浅析C++调用Java的Jar包(带参数)问题
    JarAppCall.h #include <atlstr.h> class CJarAppCall { public: CJarAppCal...
    99+
    2024-04-02
  • C++中类型推断问题分析与解决方案
    C++中类型推断问题分析与解决方案概述:类型推断是C++中的一项重要特性,它可以让程序员通过编译器自动推断变量的类型,从而简化代码并提高开发效率。然而,在一些情况下,类型推断可能会引发一些问题,例如不正确的类型推断、代码可读性差等。本文将分...
    99+
    2023-10-22
    类型推断(Type Inference) 问题分析(Problem Analysis) 解决方案(Solution)
  • python调用c++动态库dll时的参数传递问题怎么解决
    本篇内容介绍了“python调用c++动态库dll时的参数传递问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!stringC++生...
    99+
    2023-06-29
  • C++中常见的数据类型问题分析与修复方案
    C++中常见的数据类型问题分析与修复方案摘要:在C++语言中,数据类型是非常重要的概念。正确的数据类型选择和使用可以提高程序的性能和健壮性。然而,一些常见的数据类型问题仍然会出现,可能导致程序的错误或低效。本文将分析几个常见的数据类型问题,...
    99+
    2023-10-22
    数据类型 问题分析 修复方案
  • 如何分析C++函数参数引用问题
    这期内容当中小编将会给大家带来有关如何分析C++函数参数引用问题,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。在C++函数参数中,使用了引用作形参,调用时所对应的实参应该是一个数组名,这里的引用是给数组起...
    99+
    2023-06-17
  • C#入参使用引用类型要加ref的原因解析
    目录ref修饰入参的常用场景引用类型添加ref的作用是啥?总结摘一段来自官网的说明 :方法的参数列表中使用 ref 关键字时,它指示参数按引用传递,而非按值传递。 ref 关键字让形...
    99+
    2022-11-21
    c#引用类型加ref c#引用类型
  • C++中的类型推断问题详解
    C++中的类型推断问题详解在C++编程中,类型推断是指编译器根据代码的上下文环境自动推断变量的数据类型。它可以使代码更加简洁、易读,并减少了程序员的工作量。然而,类型推断也可能带来一些问题,本文将详细介绍这些问题,并提供具体的代码示例。自动...
    99+
    2023-10-22
    类型推断 (type inference) C++语言 (C++ Language) 问题详解 (Problem Ana
  • C#调用C++DLLbool返回值始终为true的问题
    目录C#调用C++ DLL bool返回值始终为true问题描述问题原因解决方案C#调用C++的DLL返回值为bool时,值混乱解决方案C#调用C++ DLL bool返回值始终为t...
    99+
    2022-11-13
    C#调用C++ DLL C++ DLL C++ DLL bool返回值 bool返回值为true
  • C语言中main()函数参数问题的示例分析
    这篇文章主要介绍了C语言中main()函数参数问题的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。#include<stdio.h>void m...
    99+
    2023-06-29
  • c++隐式类型转换存在的问题解析
    目录什么是隐式转换:为什么要进行隐式转换:隐式转换的原则:目标代码构造函数定义的隐式类型转换分析a1分析a2分析a3什么是隐式转换: c++中的基本类型并非完全对立,部分类型之间是可...
    99+
    2024-04-02
  • 使用feign传递参数类型为MultipartFile的问题
    目录feign传递参数类型为MultipartFile引入maven依赖加入配置类在feign客户端进行配置feign传参MultipartFile问题解决首先引入依赖新建feign...
    99+
    2024-04-02
  • C++ 函数调用详解:参数传递机制深入分析
    c++++ 函数调用有三种参数传递机制:传值调用(复制参数值),传引用调用(传递参数引用,可修改原始变量),指针传递(传递参数指针)。选择机制需考虑参数大小、是否需修改原始变量和效率。 ...
    99+
    2024-05-04
    c++ 函数调用
  • c#中的数据类型分为哪两大种
    c# 中的数据类型分为值类型和引用类型。值类型存储在栈中,包括基本数据类型(整数、浮点数、布尔值等)、结构体和枚举。引用类型存储在堆中,包括类、接口、数组和字符串,它们存储对对象的引用。...
    99+
    2024-04-04
    c#
  • C++中常见的数据类型问题详解
    C++中常见的数据类型问题详解,需要具体代码示例在C++中,数据类型是编程的基础。了解和正确使用不同的数据类型是编写高效,可靠代码的关键。在C++中,常见的数据类型包括整型,浮点型,字符型,布尔型和自定义类型。每个类型都有其自身的特点和用途...
    99+
    2023-10-22
    数据类型 (Data types) C++常见问题 (Common C++ Issues) 详解 (In-depth E
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作