C#调用delphi记录结构体问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#调用delphi记录结构体问题相关的知识,希望对你有一定的参考价值。

delphi代码:
1、定义的结构体
TestRecord=record
A: array[0..5] of char;
B: array[0..6] of char;
C:array[0..7] of char;
end;
2、 delphi调用函数
function test(trecord:TestRecord):integer ;stdcall ;

c#代码:
1、c#针对delphi定义的结构体
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct TestRecord

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
public string A;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 7)]
public string B;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =8)]
public string C;

2、声明调用的接口
[DllImport("Jx104.dll")]
public static extern int test(TestRecord t);
3、c#调用初始化代码
TestRecord t = new TestRecord();
t.A = "abcdef";// +((char)0).ToString();
t.B = "1234567";//+ ((char)0).ToString();
t.C = "98765432";//+ ((char)0).ToString();
JX104NET_API.test(t);

现在问题直接调用后在delphi是监控中显示结果是:
(('a', 'b', 'c', 'd', 'e', #0), ('1', '2', '3', '4', '5', '6', #0), ('9', '8', '7', '6', '5', '4', '3', #0))
发现每个结构中少最后一个字符,这是什么原因造成的,该如何解决,谢谢。

参考技术A 这个是由于你定义C#不正确造成的。
C#里(C也一样),字符串的最后都有\0结束符。你定义的C#语句public string A;的长度是6,那么它的实际允许存储的字符串为5,因为最后一个得保留存储\0.
你在赋值时,字符串"abcdef"的实际存储结构是“abcdef\0”它实际需要占用7个字节。而系统为了保证长度不越界,只能将数据截断成“abcde\0”,这也就是你在Delphi中看到的是('a', 'b', 'c', 'd', 'e', #0),的原因(C中的\0实际的ASCII值就是0,所以Delphi中最后一个字符是#0)本回答被提问者采纳

C#如何调用C++的DLL的结构体数组指针

C接口

struct PointVec3f//储存XYZ的坐标值.
float xValue;
float yValue;
float zValue;
;
extern "C" __declspec(dllimport) void getPointCloud(PointVec3f *points, int pointNum);

C#定义
public struct PointVec3f

[MarshalAs(UnmanagedType.R4)]
public float xValue;
[MarshalAs(UnmanagedType.R4)]
public float yValue;
[MarshalAs(UnmanagedType.R4)]
public float zValue;
;
PointVec3f[] points =new PointVec3f[NUM]; //points结构体数组的值我已经获取到了,想请问怎么传指针到PointVec3f *points中!Ref的方法试过了,不行!有没有其他方法,急!!
要求:1.写出C#引用接口函数的定义。
2.写出points传值给getPointCloud(PointVec3f *points, int pointNum)的过程。
可以的有分加哦!!

参考技术A 调用方法:
1、添加引用
右击项目-添加引用-浏览 找到本地的dll文件
2、using 该dll文件里面代码的名称空间
然后就可以调用dll文件里面的类(test)和方法(add)了
例如:
using aa.test
namespace conslole1

class Program

static void Main(string[] args)

Test test1=new Test();
test1.add(1, 2);


参考技术B 定义接口
[DllImport("dll文件名", CallingConvention = CallingConvention.Cdecl)]
public static extern void getPointCloud(ref PointVec3f points, int pointNum);

直接调用:
PointVec3f points;
getPointCloud( ref points, num);追问

这是C#调用C++接口,这样行不通的,试了REF传值不行,值不能传送到DLL中的函数中!只能用指针!

本回答被提问者和网友采纳
参考技术C unsafe代码块 就可以使用取地址符号&了

以上是关于C#调用delphi记录结构体问题的主要内容,如果未能解决你的问题,请参考以下文章

delphi 结构体和内存流

Delphi调用Dll返回结构体的问题?

C#调用C++的dll库怎么传递结构体中不定长度的char数组

《C#零基础入门之百识百例》(六十二)结构体类型变量 -- 学生数据记录

C#和C++传递结构体

C#如何调用C++的DLL的结构体数组指针