在C#中的指针检索参考从功能的DllImport [英] Pointers in C# to Retrieve Reference From DllImport Function

查看:208
本文介绍了在C#中的指针检索参考从功能的DllImport的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在引用我的C#项目中的DLL如下:

 函数[DllImport(FeeCalculation.dll,CallingConvention = CallingConvention.StdCall,
字符集= CharSet.Ansi)]

公共静态外部无效FeeCalculation(CIN字符串,字符串COUT,串flimit,
Frate的字符串,字符串fwindow,串fincrement ,串fbird,
串fparameter,串fvalidation,串fcoupon);



FeeCalculation功能的DLL如下输出:

 的externC__declspec(dllexport)的无效​​__stdcall FeeCalculation(字符* CIN,
的char * COUT,字符* flimit,字符* Frate的,
字符* fwindow,字符* fincrement,字符* fbird,
的char * fparameter,字符* fvalidation,字符* fcoupon);



该DLL函数返回一个引用的内部结构,字符的形式*所以如果你要引用C ++这个DLL,你会做以下做计算,并获得返回的结构:

  FeeCalculation(BUFF,(的char *)及风扇,(字符*)FL,(字符*)英尺(字符*)固件,(字符*)网络连接(字符*)铁,(字符*)及FM(字符*)VAL (字符*)CPN); 

现在,我该如何检索通过使用C#引用返回这些价值观?意思是,我该怎么做同样的事情在C#中得到返回的结构让我回来如何计算?我知道,我需要创建一个不安全的方法,但我是如何喜欢你的C ++将处理在C#中的内存地址不明



修改:以下国家使用的IntPtr但你怎么放进相同的结构使结构的字段可以被引用



编辑:这里是返回结构我感兴趣的(COUT):

 结构feeAnswer {


无符号整型费;

无符号整型tax1;

无符号整型TAX2;

无符号整型tax3;

无符号整型tax4;

无符号整型surcharge1;

无符号整型surcharge2;

无符号整型validationFee;

无符号整型couponFee1;

无符号整型couponFee2;

无符号整型couponFee3;

无符号整型couponFee4;

无符号短整型dstay; //天的逗留

无符号短整型mstay; //暂缓

};

下面是(CIN),我会一起传递,与其他结构(他们在零字节那一刻,我想这第一次工作,那么我将实施的其余部分):

 结构feeRequest {

的无符号字符日;

无符号的字符月;

无符号整型年; // 2000〜2099



无符号的字符小时;

unsigned char型分钟;

unsigned char型率;

无符号的字符验证;



unsigned char型coupon1;

unsigned char型coupon2;

unsigned char型coupon3;

unsigned char型coupon4;

};


解决方案

编辑:现在我们有结构的工作,一个更好的解决方案是可能的。刚刚宣布在C#结构匹配你的C ++结构的,而在extern声明中使用它们。



  [StructLayout(LayoutKind.Sequential)] 
公共结构feeAnswer {
公共UINT费;
公共UINT tax1;
公共UINT TAX2;
公共UINT tax3;
公共UINT tax4;
公共UINT surcharge1;
公共UINT surcharge2;
公共UINT validationFee;
公共UINT couponFee1;
公共UINT couponFee2;
公共UINT couponFee3;
公共UINT couponFee4;
公共USHORT dstay; //天的逗留
公共USHORT mstay; //暂缓
};

[StructLayout(LayoutKind.Sequential,包= 1)]
公共结构feeRequest {
公共字节日;
公共字节月;
公共UINT年; // 2000〜2099
公共字节小时;
公共字节分钟;
公共字节速率;
公共字节验证;
公共字节coupon1;
公共字节coupon2;
公共字节coupon3;
公共字节coupon4;
};

函数[DllImport(FeeCalculation.dll,CallingConvention = CallingConvention.StdCall,
字符集= CharSet.Ansi)]
公共静态外部无效FeeCalculation(
feeRequest CIN ,
OUT feeAnswer COUT,




....没有

原来的答复(我们之前有结构)以下






在我看来,这些都不是内部串引用,而是指向字符串缓冲区将被调用来填充。如果你的返回的字符串指针,那么这些将被宣布的char ** ,而不是的char *



所以我觉得这些只是标准输出参数。这里只有他们中的很多。所以你的C#互操作是这样的。

 函数[DllImport(FeeCalculation .DLL,CallingConvention = CallingConvention.StdCall,
字符集= CharSet.Ansi)]
公共静态外部无效FeeCalculation(CIN串,
[的MarshalAs(UnmanagedType.LPStr,SizeConst = 100)]
OUT字符串COUT,
[的MarshalAs(UnmanagedType.LPStr,SizeConst = 100)]
OUT字符串flimit,

或此,如果你的弦是不是真的串

 函数[DllImport( FeeCalculation.dll,CallingConvention = CallingConvention.StdCall,
字符集= CharSet.Ansi)]
公共静态外部无效FeeCalculation(CIN串,
[的MarshalAs(UnmanagedType.LPArray,SizeConst = 100 )]
OUT的byte [] COUT,
[的MarshalAs(UnmanagedType.LPArray,SizeConst = 100)]
OUT的byte [] flimit,
....


I am referencing a DLL in my C# project as follows:

[DllImport("FeeCalculation.dll", CallingConvention = CallingConvention.StdCall,
           CharSet = CharSet.Ansi)]

        public static extern void FeeCalculation(string cin, string cout, string flimit,
            string frate, string fwindow, string fincrement, string fbird, 
            string fparameter, string fvalidation, string fcoupon);

The FeeCalculation function is exported as follows in the DLL:

extern "C" __declspec(dllexport) void __stdcall FeeCalculation(char *cin, 
char *cout, char *flimit, char *frate,
char *fwindow, char *fincrement, char *fbird,
char *fparameter, char *fvalidation, char *fcoupon);

The DLL function returns a reference to it's internal structures in the form of char * so if you were to reference this DLL in C++, you would do the following to do the calculation and get the returned structures:

FeeCalculation(buff, (char *)&fans, (char *)fl, (char *)ft, (char *)fw, (char *)fi, (char *)fe, (char *)&fm, (char *)val, (char *)cpn);

Now, how do I retrieve those values that are returned by reference using C#? Meaning, how do I do the same thing in C# to get the returned structures to get my returned calculation? I know I need to create an unsafe method, but I am unclear on how to deal with the memory addresses in C# like you would in C++.

Edit: Below states to use IntPtr but how do you place into identical structure so the fields of the structure can be referenced?

Edit: Here is the returned structure that I am interested in (cout):

struct feeAnswer {


    unsigned int    fee;

    unsigned int    tax1;

    unsigned int    tax2;

    unsigned int    tax3;

    unsigned int    tax4;

    unsigned int    surcharge1;

    unsigned int    surcharge2;

    unsigned int    validationFee;

    unsigned int    couponFee1;

    unsigned int    couponFee2;

    unsigned int    couponFee3;

    unsigned int    couponFee4;

    unsigned short int dstay;       //Day Stay

    unsigned short int mstay;       //Minute Stay

};

Here is the (cin) that I would pass along with other structures (they are zero byte at the moment, I want to get this to work first then I will implement the rest):

struct feeRequest {

    unsigned char   day;

    unsigned char   month;

    unsigned int    year;   //2000 ~ 2099



    unsigned char   hour;

    unsigned char   minute;

    unsigned char   rate;

    unsigned char   validation;



    unsigned char   coupon1;

    unsigned char   coupon2;

    unsigned char   coupon3;

    unsigned char   coupon4;

};

解决方案

Edit: now that we have structures to work with, a better solution is possible. Just declare structs in C# that match your C++ structs, and use them in the extern declaration

[StructLayout(LayoutKind.Sequential)]
public struct feeAnswer {
   public uint    fee;
   public uint    tax1;
   public uint    tax2;
   public uint    tax3;
   public uint    tax4;
   public uint    surcharge1;
   public uint    surcharge2;
   public uint    validationFee;
   public uint    couponFee1;
   public uint    couponFee2;
   public uint    couponFee3;
   public uint    couponFee4;
   public ushort  dstay;       //Day Stay
   public ushort  mstay;       //Minute Stay
   };

  [StructLayout(LayoutKind.Sequential, Pack=1)]
  public struct feeRequest {
   public byte   day;
   public byte   month;
   public uint   year;   //2000 ~ 2099
   public byte   hour;
   public byte   minute;
   public byte   rate;
   public byte   validation;
   public byte   coupon1;
   public byte   coupon2;
   public byte   coupon3;
   public byte   coupon4;
   };

  [DllImport ("FeeCalculation.dll", CallingConvention = CallingConvention.StdCall,
             CharSet = CharSet.Ansi)]
  public static extern void FeeCalculation (
          feeRequest cin,
          out feeAnswer cout,
           ...



        ....

original answer (before we had structs) below


It appears to me that these are not references to internal strings, but rather pointers to string buffers that will be filled in by the call. If you were returning string pointers, then these would be declared char** rather than char*.

So I think these are just standard out parameters. There's just a lot of them. So your C# interop would look like this

[DllImport("FeeCalculation.dll", CallingConvention = CallingConvention.StdCall,
           CharSet = CharSet.Ansi)]
public static extern void FeeCalculation(string cin, 
        [MarshalAs(UnmanagedType.LPStr, SizeConst=100)]
        out string cout, 
        [MarshalAs(UnmanagedType.LPStr, SizeConst=100)]
        out string flimit,

or this if your "strings" aren't really strings

[DllImport("FeeCalculation.dll", CallingConvention = CallingConvention.StdCall,
           CharSet = CharSet.Ansi)]
public static extern void FeeCalculation(string cin, 
        [MarshalAs(UnmanagedType.LPArray, SizeConst=100)]
        out byte[] cout, 
        [MarshalAs(UnmanagedType.LPArray, SizeConst=100)]
        out byte[] flimit,
        ....

这篇关于在C#中的指针检索参考从功能的DllImport的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆