2012-01-13 13 views
4

DLL内でクラスをエクスポートする場合は、インターフェイスからそれを派生させ、そのインターフェイスをエクスポートされた関数で返すのが正しい方法ですか?dllからインターフェイスを使用するのは安全ですか

//exported dll function, which is used in the exe. 
function MyClass_Create: IMyClass; 
begin 
    result := TMyClass.Create; 
end; 

メモリ管理はどうですか?心配やクラッシュなしに異なるインターフェースや文字列を渡すことはできますか?

IMyClass = interface 
    procedure SetString(aMsg: string); 
    function GetString: string; 

    procedure SetClass(aClass: ITestClass); 
    function GetClass: ITestClass; 
end; 

答えて

3

このようなインターフェイスを使用すると、インターフェイスを実装するオブジェクトが作成され、同じヒープで解放されます。

しかし、これは動的な文字列型が割り当てられ、異なるヒープで割り当て解除されるという問題を解決しません。これには多くの解決策が考えられますが、私の考えでは、モジュールの境界を越えてWideStringを使用するのが最良の方法です。

WideString型はCOM BSTRのラッパーで、共有COMヒープに割り当てられます。インターフェイスにWideStringを使用する必要があります。実装するクラスの内部では、ネイティブのDelphi文字列を使用できます。

文字列と同じように問題が発生するため、動的配列も問題になります。モジュールの境界を越えて動的配列をパースしようとする試みは安全ではありません。便利なWideStringに類似した解決策はありません。バリアント配列を使用することはできますが、それはWideStringと比較してかなり厄介です。

5

インターフェイス参照はメモリ管理と直交しています。通常、dllからインタフェース参照を返す関数をエクスポートし、メモリ管理は気にしません。参照カウントインターフェイスでは、インターフェイスを実装するオブジェクトインスタンスがdllでも解放されることを確認できます。

文字列が異なります。インターフェイスをエクスポートするかフラット関数をエクスポートするかは関係ありません。同じ制限が適用されます。

ご質問のタイトルが間違っています.Delphiには「インターフェイスインスタンス」がありません。

+0

インターフェースの循環参照を使用するときに潜在的なメモリリークの問題を認識して(すなわち、共有インターフェイスを指す実装クラスである) - この場合には、Delphiはガベージコレクタまたは「弱いポインタをゼロ」機能を欠いています。 http://blog.synopse.info/post/2011/12/08/Avoiding-Garbage-Collector%3A-Delphi-and-Apple-on-the-same-side –

+0

を参照してください。循環参照は参照カウントによくある問題です。汚れたトリック 'Pointer(IntRef):= nil'は、refcountを変更せずにnullリファレンスを使用すると助けになります。 – kludg

関連する問題