在C#中的指针检索参考从功能的DllImport
-
23-09-2019 - |
题
我引用的DLL在我的C#项目如下:
[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);
在FeeCalculation功能如在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);
在DLL中的函数返回一个引用的内部结构,焦炭的形式*所以如果你要引用这个DLL在C ++中,你会做以下做计算,并获得返回的结构:
FeeCalculation(buff, (char *)&fans, (char *)fl, (char *)ft, (char *)fw, (char *)fi, (char *)fe, (char *)&fm, (char *)val, (char *)cpn);
现在,我该如何检索使用C#返回的这些值的参考?意思是,我该怎么做在C#一样的东西来获取返回的结构让我回来如何计算?我知道我需要创建一个不安全的方法,但我如何喜欢你用C ++会处理在C#中的内存地址不清楚。
编辑:下面状态中使用的IntPtr但你怎么放进相同的结构,因此结构的字段可以被引用
编辑:这是返回结构我对(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
};
下面是(CIN),我会一起传递与其它结构(它们是目前零字节,我想这首先工作,那么我将实施的其余部分):
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;
};
解决方案
编辑:现在我们已经结构与工作,更好的解决方案是可能的。刚刚宣布在C#结构匹配您的C ++结构这一点,在extern声明中使用它们
[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,
...
....
原来的答复(之前,我们有结构)以下
在我看来,这些都不是内部串引用,而是指向字符串缓冲区,将在由呼叫来填补。如果你的返回的字符串指针,那么这些将被宣布char**
而非char*
。
所以我觉得这些只是标准输出参数。这里只是他们中的很多。所以,你的C#互操作是这样的
[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,
或此,如果你的“弦”是不是真的字符串
[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,
....
其他提示
在字符*在这种情况下的参数不是字符串而是指针表示数据的原始字节的块。您应该 Marshal.AllocHGlobal元帅的参数作为IntPtr的类型的实例,并结合以创建的存储器块,然后 Marshal.PtrToStructure 一>到该存储器块转换成可用的.NET类型。
作为一个例子:
[StructLayout(LayoutKind.Sequential)]
struct MyUnmanagedType
{
public int Foo;
public char C;
}
IntPtr memory = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MyUnmanagedType)));
try
{
FeeCalculation(memory);
MyUnmanagedType result = (MyUnmanagedType)Marshal.PtrToStructure(
memory, typeof(MyUnmanagedType));
}
finally
{
Marshal.FreeHGlobal(memory);
}
要回答你的编辑,你需要创建一个结构,然后使用的 StructLayoutAttribute 上的字段,以使字节顺序和填充所述原来一样的dll一样。