c# 调用c库dll 遇到char*转string的解决办法

原创 2018年04月17日 15:48:31

最近由于有个未知的设备需要用到modbus通讯协议,底层需要与PLC通讯,坤跌,PLC啥型号也不清楚封在里面不能拆,前人只留了几个不能运行的QT代码以及不完整的文档。用惯了C#想要重新学QT,真不知猴年马月能完成项目。于是乎找了一个开源的基于C语言开发的modbus库,撸起袖子干了起来。撸代码的过程中,遇到调用c 库的char*转c#的string多次不成功的情况,各种冒框啊,折腾了大半天才算解决,最终记录如下,以备后面遇到同样的坑能少走点弯路。

.h file

#pragma once
#define LineMaxLen 2048  
#define KeyMaxLen 128  
#define MaxFileLength 1024*10  
#if defined(_MSC_VER)
# if defined(DLLBUILD)
/* define DLLBUILD when building the DLL */
#  define MODBUS_API __declspec(dllexport)
# else
#  define MODBUS_API __declspec(dllimport)
# endif
#else
# define MODBUS_API
#endif

static char value[KeyMaxLen];//需要定义为全局变量,编译成dll后才能被c#正常调用,否则指针地址有数据,指针内容看到的返回值为空

MODBUS_API char* getValue();
MODBUS_API int sum(int a, int b);

#endif  

.c file

char* getValue()//char key[KeyMaxLen]
{			
	memset(value, 0, sizeof(value));
	strcpy(value, "abcdefgh");
	return  value;
}

.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace RotPlatformControl_CsDll
{
    public class CRotPlatformControl
    {
        [DllImport("modbus.dll", EntryPoint = "getValue", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr getValue();//不能用string,使用IntPtr对应于c中的函数返回类型char*
        
    }
}
private void buttonHome_Click(object sender, EventArgs e)
        {           
            IntPtr temp = CRotPlatformControl.getValue();
            res=Marshal.PtrToStringAnsi(temp).ToString();
            temp = IntPtr.Zero;

            lblMessage.Text = res.ToString();
        }
UI显示“abcdefgh” 说明dll已经调用成功。



总结:

1. const char* 直接换成string

2. char*做形参或返回值,需要换成IntPtr

3. char*做形参并想要获取char*内容,使用ref IntPtr无用。只能将该char*改为返回值获得。

4. C库文件中需要定义为全局变量,编译成dll后才能被c#正常调用,否则指针地址有数据,指针内容看到的返回值为空。


modbus封库源码

https://download.csdn.net/download/ericwuhk/10352801



C# 调用C写的DLL时 对应的char* 类型转化为 ref byte

C中代码: void read( char *filename ) { ....... } C#中代码: [DllImport("myC.dll", EntryPoint = "read...
  • diyoosjtu
  • diyoosjtu
  • 2012-08-07 10:59:36
  • 4606

C#调用C++dll,C++中char*与C#类型的对应关系

最近在编写C#上位机应用程序,需要调用C++的dll,期间遇到dll接口库中char*类型纠结了很久,试过string,StringBuilder,StringBuilder结果都以失败告终,通过查找...
  • u014496078
  • u014496078
  • 2015-11-13 09:35:05
  • 7725

C#调运C++的DLL返回中文字符串乱码问题

C++ DLL extern "C" __declspec(dllexport) char* GetStr() { string s1 = "大大"; char *data; int len =...
  • BleuRever
  • BleuRever
  • 2016-12-02 10:10:21
  • 7370

C# 调用C++dll中接口,返回const char*

const char* 是由构建的JSON 转 std::string ( toStyledString() ) 然后 c_str();在C#中使用的时候就无法获取正确的字符串;使用 string来接...
  • u011451070
  • u011451070
  • 2018-03-07 20:26:04
  • 32

c#调用c语言dll,形参有char*

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin...
  • bejustice
  • bejustice
  • 2014-07-30 11:17:34
  • 2195

C# 调用C/C++ Dll(参数含char*指针,返回char*指针)

动态库: //MyPointDll.h extern"C" _declspec(dllexport) char* strcpyTest(char* dest,char* sour);
  • youqingyike
  • youqingyike
  • 2015-08-16 12:12:35
  • 7873

C#调用C++的Dll(参数和返回值為char* TCHAR*)

想要在C#和C++之间进行字符串传递会涉及到两件事情: 1.C#的string和C++的字符串首指针要怎么对应.   2.字符串分为ANSI和UNICODE. C++ 头文件接口: //Fil...
  • donnie88888888
  • donnie88888888
  • 2016-12-02 16:20:42
  • 3450

C语言的DLL怎么给VB返回String(char*)呢

这个问题很少有资料可以搜索得到,主要是因为现在的程序员要么是C/C++,要么VB(.NET),即有一种钟爱的语言.跟罗sir交流了一下,罗sir是C#骨灰级玩家,专攻网络开发,他认为DLL加载到exe...
  • prsniper
  • prsniper
  • 2010-03-28 06:56:00
  • 3063

Python:使用ctypes库调用外部DLL(附带ctypes c 类型转换图)

2010-04-04 23:36 by 无常, 22558 阅读, 6 评论, 收藏, 编辑 前言 朋友的公司是做GPS的,上周联系到我要帮做个程序把他们平台的车辆定位跟踪数据和省里的平台对接。看...
  • kjlrzzyffmx
  • kjlrzzyffmx
  • 2015-12-07 15:25:23
  • 2002

C#调用CDLL带指针参数的函数

  • 2009年04月16日 16:04
  • 36KB
  • 下载
收藏助手
不良信息举报
您举报文章:c# 调用c库dll 遇到char*转string的解决办法
举报原因:
原因补充:

(最多只允许输入30个字)