D与C#的交互:C#调用D的dll

D语言的简捷很让人着迷,对于一些用C#写的老代码,想用D写成dll,来提高一下效率。
本文用一个简单例子来展现一下c#调用d的dll。
1、D代码:

mydll.d:

module mydll;

 import std.stdio;
 import std.file;
import std.string;

public struct Struct1
{
    protected int a;
    protected ulong b;
    protected immutable(char)* c;
}
public struct Struct2
{
    protected int a;
    protected ulong b;
}
 export extern(C) void dllprint(ref int a,ulong b,immutable(char)* str,out wchar* strref,Struct1 struct1,ref Struct2 struct2) //
 { 
     writeln("-------hello dll world,from D to C#!-------");
     auto f = File("test.txt", "w");
     f.writeln("执行D的dll后的结果:");
     f.writeln("传入D的int值:",a);
     f.writeln("传入D的ulong,string 值:",b,",",fromStringz(str));

     f.writeln("传入D的结构的值:",struct1.a,",",struct1.b,",",fromStringz(struct1.c));

     f.writeln("---------from D to C#---------------");

     a=10;
     f.writeln("准备传入C#的int值:",a);

     struct2.a =4;
     struct2.b = 7000;
     f.writeln("准备传入C#的结构的int值:",struct2.a);
     f.writeln("准备传入C#的结构的int值:",struct2.b);

     f.writeln("准备传入C#的字符串:","aaa");
     strref = cast(wchar*)"aaa";
     f.writeln("------------------------");
     f.writeln("传入D的结构:",struct1);
 }

2、c#代码

Program.cs:

using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
    class Program
    {
      public struct Struct1
        {
           internal int a;
           internal ulong b;
           internal string c;
        }
        public struct Struct2
        {
            internal int a;
            internal ulong b;
        }
        [DllImport("TestCsharp_D.dll")]
        public static extern void dllprint(ref int a,ulong b,string str,out IntPtr strRef, Struct1 struct1,ref Struct2 struct2);
        static void Main(string[] args)//[MarshalAs(UnmanagedType.LPWStr)] 
        {
            int a = -1;
            ulong b = 10101;
            string pp = "HElLo";
            IntPtr strref = IntPtr.Zero;

            Struct1 struct1;
            Struct2 struct2;
            struct1.a = 2;
            struct1.b = 50000;
            struct1.c ="struct1_1";

            struct2.a = 3;
            struct2.b = 60000;
            // struct2.c = "struct2_2";
            Console.WriteLine("准备传入D的int值:{0}",a);
            Console.WriteLine("准备传入D的ulong,string 值:{0},{1}", b, pp);
            Console.WriteLine("准备传入D的结构的值:{0},{1},{2}", struct1.a, struct1.b, struct1.c);
            Console.WriteLine();

            dllprint(ref  a, b, pp,out strref, struct1, ref struct2);
            Console.WriteLine();

            Console.WriteLine("传入C#的int值:{0}",a);
            Console.WriteLine("传入C#的结构中的int值:{0}", struct2.a);
            Console.WriteLine("传入C#的结构中的ulong值:{0}", struct2.b);
            Console.WriteLine("传入C#的字符串:{0}", Marshal.PtrToStringAuto(strref));
            Console.WriteLine("--------------------------");
            Console.WriteLine("传入C#的结构:{0}", struct2);

            //Marshal.FreeCoTaskMem(strref);//不需要,D自动Free
            Console.Read();
        }
    }
}

3、结果图:

这里写图片描述

4、小结:
C#传给D的数据,除字符串在D里需要std.string.fromStringz()函数处理,其它都是直接传输。
D回传给C#的数据,请加 ref 或out参数。另外字符串在c#里及D里的声明都不一样,而且传前及传后都需要处理一下。
若您有什么好的建议,请在评论里写上,谢谢!

注:运行环境:c#4.0及以上,dmd 2.07.1.1 ,winXp及以上

项目文件下载(VS2015)

本文为原创,转载请注明出处:出自“未来之眼”

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值