C++ 定义

typedef struct Stu
{
public:
int Age;
char Name[20];
};

typedef struct Num
{
int N1;
int N2;
};

extern "C" __declspec(dllexport) void FindInfo(Stu& stu)
{
stu.Age = 10;
strcpy_s(stu.Name, "徐滔");
}

extern "C" __declspec(dllexport) int Add(int a,int b)
{
return a + b;
}

extern "C" __declspec(dllexport) int GetNumSum(Num* num)
{
return num->N1 + num->N2;
}

extern "C" __declspec(dllexport) bool InputInfo(int age,char name[20], Stu* stuInfo)
{
stuInfo->Age = age;
char* test = name;
strcpy_s(stuInfo->Name, name);
return true;
}

在C# 中需要重新定义结构

[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public struct Stu
{
public int Age;
[System.Runtime.InteropServices.MarshalAs(UnmanagedType.ByValTStr,SizeConst =20)]
public string Name;
}

注意c# 中 和c++ 中的数据类型的对应。

public struct Num
{
public int N1;
public int N2;
}

申明 调用函数

[DllImport("MyFuncDll.dll", EntryPoint = "FindInfo", CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Unicode)]
extern static void FindInfo(ref Stu stu);
[DllImport("MyFuncDll.dll", EntryPoint = "Add", CallingConvention = CallingConvention.Cdecl)]
public extern static int Add(int a, int b);

[DllImport("MyFuncDll.dll", EntryPoint = "GetNumSum", CallingConvention = CallingConvention.Cdecl)]
public extern static int GetNumSum(ref Num num);

[DllImport("MyFuncDll.dll", EntryPoint = "InputInfo", CallingConvention = CallingConvention.Cdecl,
CharSet =CharSet.Ansi)]

特别要注意 CharSet 属性的设置。

调用测试

int re = Add(1, 3);
Num n = new Num() { N1 = 1, N2 = 2 };
int r = GetNumSum(ref n);
Stu stu = new UseCppDll.Stu();
FindInfo(ref stu);
MessageBox.Show(stu.Name);

在c#中调用C++传递 char[]类型的参数

string sna = "系统";
bool b = InputInfo(23, sna, ref stuInfo);

//-------------------------------------------------------------

C# 调用 C++ dll返回字符串问题

做个简单的例子,将传入的字符串复制后再返回…

C++中定义方法:

EXTERN_C __declspec(dllexport) bool TryCopyStr(char* src, char** desstr)
{
    _memccpy(*desstr, src,0, strlen(src));
     return true;
}

参数: src —源字符串

参数:desstr—目标字符串(也就是要将返回值赋给该参数),注意其类型为 char**

C# 代码:

//dll调用申明

[DllImport("dotNetCppStrTest.dll", EntryPoint = "TryCopyStr", CallingConvention = CallingConvention.Cdecl)]
public extern static bool TryCopyStr(string src,ref StringBuilder desStr);

//测试方法

private void TestTryGetStr()

{

bool suc = false;
        StringBuilder resultStrBuilder = new StringBuilder();
        string srcStr = "this is string from .net 从.net传过去的字符串";
        suc = TryCopyStr(srcStr,ref resultStrBuilder);

}

注:

参数 desStr 是 StringBuilder 类型,而不是 String 类型。因为在dll中对该参数进行了重新赋值,也即是参数值发生了改变,String 类型的值是不能改变的。

此方法在VS2015测试通过。

C# 调用C++ 结构体示例的更多相关文章

  1. C# 调用C++结构体

    参考网址:C#调用C/C++动态库,封装各种复杂结构体._liguo9860的专栏-CSDN博客 现在公司要做一个使用C#程序调用C++的一个DLL库,解析文件的功能.所以在网上找了一些资料.     ...

  2. python 调用dll 动态链接库 结构体参数及回调函数等示例

    结构体示例: 这里是 C 代码的部分,主要是结构体的声明和回调函数定义. // 新版本定义 typedef enum { DevCard, DevLocator, DevReader } DevTyp ...

  3. C#调用C/C++动态库 封送结构体,结构体数组

    一. 结构体的传递 #define JNAAPI extern "C" __declspec(dllexport) // C方式导出函数 typedef struct { int ...

  4. C#调用C/C++动态库,封装各种复杂结构体

    C#调用C/C++动态库,封装各种复杂结构体. 标签: c++结构内存typedefc# 2014-07-05 12:10 6571人阅读 评论(1) 收藏 举报  分类: C(8)  C#(6)  ...

  5. 【转】C++ - 结构体构造函数使用总结

    声明 转载自:https://www.cnblogs.com/wlw-x/p/11566191.html 关于结构体构造函数使用总结 三种结构体初始化方法 1.利用结构体自带的默认构造函数 2.利用带 ...

  6. C++ - 结构体构造函数使用总结

    关于结构体构造函数使用总结 三种结构体初始化方法 1.利用结构体自带的默认构造函数 2.利用带参数的构造函数 3.利用默认无参的构造函数 要点: 在建立结构体数组时,如果只写了带参数的构造函数将会出现 ...

  7. go 基础 结构体

    结构体是类型中带有成员的复合类型.go语言使用结构体和结构体成员来描述真实世界的实体和实体对应的各种属性. go语言中的类型可以被实例化,使用new和&构造类型实例的类型是类型的指针. 结构体 ...

  8. C# 中的只读结构体(readonly struct)

    翻译自 John Demetriou 2018年4月8日 的文章 <C# 7.2 – Let's Talk About Readonly Structs>[1] 在本文中,我们来聊一聊从 ...

  9. C# 8: 可变结构体中的只读实例成员

    在之前的文章中我们介绍了 C# 中的 只读结构体(readonly struct)[1] 和与其紧密相关的 in 参数[2]. 今天我们来讨论一下从 C# 8 开始引入的一个特性:可变结构体中的只读实 ...

随机推荐

  1. setTimeout与setInterval参数之String

    今天无意中给某网友解答了一些setTimeout的问题,发现一个有趣的东西. 以前我总认为setTimeout的第一个参数只能function,后面发现string也能执行.那问题来了,String做 ...

  2. 移动端300ms的点击延迟以及解决方案

    [今天做在移动端的一些效果时,我选择使用动画而不是用过渡,这个300ms的点击延迟是我为什么使用动画而不使用过渡最主要的一个原因] 动画和过渡 共同点:都是css控制DOM运动, 不同点: 1.过渡: ...

  3. Wireshark网络端点和会话

    如果想让网络进行正常通信,你必须至少拥有两台设备进行数据流交互.端点(endpoint)就是指网络上能够发送和接受数据的一台设备.举例来说,在TCP/IP的通信中就有两个断电:接收和发送数据系统的IP ...

  4. 005.Getting started with ASP.NET Core MVC and Visual Studio -- 【VS开发asp.net core mvc 入门】

    Getting started with ASP.NET Core MVC and Visual Studio VS开发asp.net core mvc 入门 2017-3-7 2 分钟阅读时长 本文 ...

  5. jmeter- Java-POST接口使用get与json格式传参

    在测试过程中发现各种接口传参形式,今天就来说说小编遇到的一种,接口请求方式为POST:URL传参以GET形式并携带JSON 可能这样诉说有不少同学不太理解. 如图: 上图所示就是一般get请求传参格式 ...

  6. 集合的定义,操作及运算 (Python)

    集合的定义: 集合和列表([  ]) 与  字典 ( {    }) 不同,没有特别的特别的语法格式.可以使用set () 创建. 集合同字典一样是无序的.也是不具有重复性的.因此可以把列表变成集合进 ...

  7. request.setcharacterencoding()和request.setcontenttype

    1.request.setCharacterEncoding()是设置从request中取得的值或从数据库中取出的值 指定后可以通过getParameter()则直接获得正确的字符串,如果不指定,则默 ...

  8. Java并发编程笔记——技术点汇总

    目录 · 线程安全 · 线程安全的实现方法 · 互斥同步 · 非阻塞同步 · 无同步 · volatile关键字 · 线程间通信 · Object.wait()方法 · Object.notify() ...

  9. (转)Java线程:大总结

    Java线程:大总结   Java线程是Java语言中一个非常重要的部分,Java5之前,多线程的语言支持还是比较弱的,内容也较少,写一个复杂的多线程程序是相当有挑战性的.   在Java5以后,Ja ...

  10. Spring源码情操陶冶-AbstractApplicationContext#finishBeanFactoryInitialization

    承接前文Spring源码情操陶冶-AbstractApplicationContext#registerListeners 约定web.xml配置的contextClass为默认值XmlWebAppl ...