C#使用链表结构(intptr)与c语言 dll配合使用。

在本文开始前,我认为有必要简单介绍一下链表的概念,或者本人对于链表的个人理解,通过在结构中定义和自己相同类型的指针变量,并配合C语言的动态开辟内存,实现类似动态可变长度的动态数组功能。
链表是C语言中的一种重要的重要结构,而在.net中,由于其面向对象的特性,在安全情况下,开发人员无法直接操作内存,即无法使用指针,于是在隶属值类型的结构体类型中,无法直接实现链表的功能。在全部托管的环境下,这是完全可以的,但有时.net开发人员需引用非托管语言所编写的dll。关于.net如何使用c语言的dll的相关文献已经很多,这里推荐http://my.oschina.net/bubifengyun/blog/96252这篇文章,本文详细对在CLR安全情况下,C#如何实现链表结构,以与c dll映射。
我的MyDll.h代码如下:
#ifndef LIB_H
#define LIB_H
typedef struct MyStruct {
int MyVal;
MyStruct *Next;
}MyStruct;

extern “C” _declspec(dllexport) MyStruct* GetStruct(MyStruct st);
#endif
我的MyDll.cpp代码如下:
#include “stdafx.h”
#include “MyDLL.h”//貌似这两个头文件的顺序不能颠倒。我试了很多次,但是不能确定。
#include “stdlib.h”
MyStruct
GetStruct(MyStruct st) {
(
(st+1)).MyVal = StateNum++;
MyStruct *ms;
ms = (MyStruct )malloc(1sizeof(MyStruct));//函数内开辟一个数组;
(*ms).MyVal = 2;
st->Next = ms;//将对应IntPtr通用指针指向非托管内存地址
return st;
}

C#代码如下:
namespace CDllInvoker {
public struct MyStruct{
public int MyVal;
public IntPtr Next;
}
[DllImport(“DLLInvoked.dll”, CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]//因为此处c语言dll项目为DLLInvoked,所以其生成的dll文件就是DllInvoked.dll
public extern static IntPtr GetStruct(ref MyStruct st);
static void Main(string[] args) {
int sizeOfmyStruct = Marshal.SizeOf(typeof(MyStruct));
MyStruct[] stArray = new MyStruct[10];
IntPtr ptr = GetStruct(ref stArray[0]);
MyStruct next = (MyStruct)Marshal.PtrToStructure(stArray[0].Next, typeof(MyStruct));
Console.WriteLine(next.MyVal);
Console.Read();
}
}

发布了5 篇原创文章 · 获赞 3 · 访问量 2112

猜你喜欢

转载自blog.csdn.net/qq_26023835/article/details/104162727