ポインタの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の関数への参照を返します内部構造の形式でchar*うした場合はこちらを参照し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,
....
他のヒント
この場合のchar *パラメータは、データを表す生のバイトのチャンクに文字列が、ポインタではありません。あなたは 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ました。