C#でDelphi DLLに渡すtStringList
-
02-07-2019 - |
質問
次のように定義された関数を持つDelphi DLLがあります
submitJobStringList(joblist:tStringList; var jobno:Integer):Integer;
C#からこれを呼び出しています。 tStringListがC#に存在しないとして最初のパラメーターを宣言するにはどうすればよいですか。私は現在、次のような宣言を持っています:
[DllImport("opt7bja.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int SubmitJobStringList(string[] tStringList, ref int jobno);
ただし、呼び出すと、メモリアクセス違反の例外が発生します。
誰もがC#からtStringListに正しく渡す方法を知っていますか?
解決
あなたはおそらくこれで運がないでしょう。 TStringListは単なる配列ではなく、本格的なクラスであり、実装の詳細は.NETで可能なこととは異なる場合があります。 Delphi VCLのソースコード(つまり、ある場合)を見て、C#でクラスを再構築できるかどうかを確認し、親友であるInterop Marshallerの助けを借りてそれを渡します。 Delphiの文字列型であっても.NETの文字列型とは異なり、マーシャラーに何をすべきかを伝えずに渡すと、おそらく文字配列として渡されることに注意してください。
それ以外の場合、Delphi DLLを変更することをお勧めします。非Delphiクライアントで使用されるDLLのDelphi固有のものを公開することは決して良いことではありません。パラメーターをPCharの配列にすると、問題ないはずです。
他のヒント
これがDLLの場合、代わりに文字列の配列を受け入れるように関数を書き換えます。クラスをDLLパラメーターとして渡さないでください。
または、何らかの理由でTStringListを本当に使用したい場合は、DelphiのVCL.Netを任意の.Net言語から使用できます。
TIniFileを使用した古い例: http://cc.codegear.com/Item/22691
この例では、Delphi 2005で.Net 1.1を使用しています。Delphi2006および2007は.Net 2.0をサポートしています。
DLLを制御せず、変更できない場合、または変更しない場合は、言語間でより使いやすいパラメーターを使用して、独自のDelphiラッパーを常に別のDLLに記述できます。
クラスをDLL関数のパラメーターとして保持するのは、本当に悪い形式です。
デルファイとC#の使用方法は明確ではありません。 C#から呼び出すWin32 DLLを作成したようです。これにはPInvokeを使用する必要があります。
VCLの完全な移植が利用可能であるため、ソースコードを使用して.NET DLLを作成することをお勧めします。ご希望であれば、さらに詳しく説明することもできます。...
理論的には、厳密に型指定されたオブジェクト参照の代わりにポインター(C#IntPtr型としてキャスト)を使用して(または多分他の型でラップして、 (安全でないブロックを宣言します)、しかし、本質的なキャッチはこれです:Delphiランタイムは、オブジェクトのメモリの割り当てと割り当て解除のためのメカニズムでなければなりません。そのためには、DelphiでコンパイルされたDLLでTStringListクラスのコンストラクタとデストラクタを呼び出す関数を宣言し、Delphi DLLがShareMemユニットを使用していることを確認し、参照カウントのインクリメントとデクリメントを行う必要があります。 Delphi AnsiStringsがDLLを出る前と入った後、できればDelphi DLLからエクスポートされた関数として。
要するに、同じプロセスで2つのメモリマネージャー(.NET CLRとDelphiのアロケーター)をジャグリングする必要があり、メモリを手動で管理する必要があるため、多くの作業です。 " fool" Delphiメモリマネージャーとランタイム。この設定に縛られている特別な理由はありますか?解決しようとしている問題をより高いレベルで説明できますか?
Hemant Jangidが言ったように、コードを.NET dllとしてコンパイルし、C#プロジェクトでそのアセンブリを参照することで、これを簡単に行えるはずです。
もちろん、これは、お使いのDelphiのバージョンにDelphi.NETがインストールされている場合にのみ可能です。
c#について詳しくはありませんが、コンテキスト間で文字列リストを転送するために使用する手法は、.textプロパティを使用してリストを表す文字列を取得し、そのプロパティを「反対側」に割り当てます。
通常、壁にひもを付けると、完全に吹き飛ばされたオブジェクトになります。