在C#中的指针检索参考从功能的DllImport [英] Pointers in C# to Retrieve Reference From DllImport Function
问题描述
我在引用我的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屋!