2

C++ で記述された外部デバイスを制御する DLL があります。しかし、開発では ANSI C (c++ はサポートされていません) を使用しているため、純粋な C 構文でしかコードをコンパイルできません。

C++ で記述された DLL を私の C コードにロードすることは可能でしょうか? DLL は言語に依存しますか? C++ DLL、C DLL、または C# DLL と呼ばれるものはありますか?

もしそうなら、同じ言語のコードでのみ DLL を呼び出すことができるということですか? 私はオンラインで検索を行い、C++ 環境で C を呼び出すことについて何かを見つけましたextern C {}。ステートメントを使用することをお勧めします。しかし、私のケースは正反対だと思います。C で C++ を呼び出す必要がありますが、コンパイラが C++ をサポートしていないときにどうすればそれを行うことができますか?

4

4 に答える 4

2

C++ で記述された DLL を私の C コードにロードすることは可能でしょうか。

はい、すべてのランタイム要件が満たされている限り、作成に使用された言語に関係なく、C コードを使用して共有オブジェクト (または動的にリンクされたライブラリ) を読み込むことができます。

DLL 言語に依存していますか?

共有オブジェクト自体は何らかの形式のバイナリです (つまり、Linux ではELFです)。それが作成された言語とは何の関係もありません。たとえば、理論的には 16 進エディタで DLL を作成できるため、作成元の «言語» はありません。

それは、C++ DLL、C DLL、または C# DLL と呼ばれるものですか?

理論的には、たとえば C++ コードをコンパイルして作成されたことがわかっている場合、DLL を «C++ DLL» として呼び出すことができます。あるいは、C++ 固有のランタイム ライブラリに依存している場合もあります。ただし、システムの観点からは、これは依然として実行可能なバイナリ オブジェクトであり、システムはそれを作成するために使用された言語やコンパイラ (存在する場合) を気にしません。

…同じ言語のコードでのみ DLL を呼び出すことができるということですか?

いいえ。

オンラインで検索したところ、C++ 環境で C を呼び出すことについて何かが見つかりました。

コンピュータ プログラムとオペレーティング システムまたは別のプログラムとの間の低レベル インターフェイスを記述するApplication Binary Interface (ABI)に注意する必要があります。C++ の場合、他のすべてに加えて、シンボル名がどのようにマングルされているか、どの例外メカニズムが使用されているかを知る必要があります。そして、それは特定のマシン/オペレーティング システム/コンパイラの組み合わせに依存します。

そのことを知っていて、«C++ DLL» がロード可能で実行可能である (つまり、実行時の依存関係がすべて存在する) 場合、C プログラムでその DLL をほとんどホストできます (その DLL が «extern "C" を介して C インターフェイスを提供しなくても)。 » ステートメント)。たとえば、オブジェクト (つまり、クラス) のサイズ、そのレイアウト要件、マングルされたコンストラクター/デストラクター関数名 (存在する場合) がわかれば、メモリを割り当ててそのオブジェクトを構築できます。次に、メソッドのマングル名と «this» ポインターがどのように渡されるかを知っていれば、それらを呼び出すことができます。

それをしないでください!

そうは言っても、これはあなたがやろうとする必要がある最後のことです。その DLL の ABI に一致する適切な C++ コンパイラを取得し、使用するインターフェイスを記述したヘッダー ファイルを取得して、通常のユーザーと同じように使用する方がはるかに簡単です。ハッキングを試みるよりも、その DLL の機能を自分で実装する方が簡単な場合もあります。では、他のものを試してみてください。善良なサマリア人がコメントですでに示唆しているように、「DLL を提供した人に、DLL の適切な使用方法を尋ねてください」

幸運を!

于 2013-07-29T22:14:57.767 に答える
2

これは、DLL 内の関数の実装に大きく依存します。

std::stringクラス オブジェクトを返す、型(または他のクラス オブジェクト) のパラメーターを取得する、例外をスローするなど、関数が C++ 機能を公開している場合、Cから意味のある方法でそれを使用するのに苦労することになります。

ただし、エクスポートされたすべての関数が標準 C インターフェイスを使用している場合 (文字列が へのポインターでcharあり、例外 [1] がなく、クラス オブジェクトが返されないなど)、はい。ただし、たとえば「例外がリークする」場合、誰も DLL を使用したくないことに注意してください。

[1] これは、呼び出しが例外をスローしないことが 100% 確実でない限り (詳細については後述しますtry { code goes here } catch(...) { catch-all code here })、すべての関数で使用する必要があることを意味します。

現代の C++ で例外を回避することは非常に困難です。たとえばvector<int> v; ... v.push_back(42); ...、例外を引き起こす可能性のある無害なステートメントです。bad_alloc

要約すると、すべてを正しく行うのは非常に複雑です。実際に C++ DLL を作成したい場合は、それを C++ から使用する必要があります。C 呼び出し可能な DLL が必要な場合は、原則として C で記述します。

于 2013-07-29T22:19:16.527 に答える