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

来源:互联网 发布:黑白网络黑客教程 编辑:程序博客网 时间:2024/06/05 01:58
       在本文开始前,我认为有必要简单介绍一下链表的概念,或者本人对于链表的个人理解,通过在结构中定义和自己相同类型的指针变量,并配合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_Htypedef 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(1*sizeof(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();        }
}


0 0
原创粉丝点击