8

OpenTK で SPARK パーティクル システムを使用しようとしています。
私のプロジェクトにはフォルダー内のヘッダー ファイルが含まれており、他のヘッダー ファイルのみを含む 2 つのヘッダー ファイルがあり、フォルダーにはソース ファイルも含まれています。
これまでにいくつかのアプローチを試しましたが、まだ何もうまくいきませんでした。

1.P/インボーク

これは、dll をビルドした C++ プロジェクトにいくつかのコードを記述し、次にDllImportC# で属性を使用しています (明らかに が必要using System.Runtime.InteropServices;です)。これはクラスでは機能せず、クラス外のメソッドに対してのみ機能するという難しい方法を発見したため、このアプローチは効果がありませんでした。

2.ラッパークラス

これは、元のクラスへのポインターを含むクラスを作成しています。マネージ コードからアンマネージ コード (自動メモリ管理なし) を呼び出すと、実際には問題が発生することがわかりました。そのため、ラッパー クラスが必要であり、メソッドのシグネチャを再定義して、元のメソッドを呼び出させる必要があります。

もちろん、これには、クラスやメソッドの名前をより適切に付けるなどの利点がありますが、ライブラリが非常に大きいため、その労力がわかります。

3. 自動ラッパーの使用:

これは、特に xInterop++ を使用する場合に適したアプローチです。私はこれについて本当に楽観的で、うまくいくと思っていました。「.h ファイルと dll をください。.NET dll をビルドします」と表示されています。良いですが、そうするとエラーが発生します。簡単に言えば:

.h ファイルと dll に一貫性があり、ライブラリが C++ プロジェクトで機能することを確認する必要があります。

このエラーに対処するために、いくつかのことを試しました。

  1. dll に何が含まれているかを知る: グーグルやこのサイトから学んだように難しいため、失敗しました。
  2. ヘッダー ファイルを新しいプロジェクトに配置してビルドする: エラーを受け取り、それらを修正してからプロジェクトをビルドすると、うまくいきました。ヘッダー ファイルを含む dll ファイルを xInterop にアップロードしました。次に、見つかったクラスに通知しましたが、何も見つからなかったと述べました。私は検索して、次のステートメントを使用して必要なすべてのクラスをマークすることにより、dll によってどのクラスを公開する必要があるかをコンパイラに通知する必要があることを知りました_declspec(dllexport)
  3. 検索と置換を使用してこの問題を修正し、再試行したところ、クラスが表示されたので、xInterop を起動して同じエラーを受け取りました。
  4. dll が機能することを確認するように求められました。ファイルが機能することを確認した後、プログラムを起動するとリンカー エラーが発生しました。

これが私が立ち往生している場所です。これらは私が得るリンカエラーです:

main.obj : エラー LNK2019: 未解決の外部シンボル "void __cdecl SPK::swapParticles(class SPK::Particle &,class SPK::Particle &)" (?swapParticles@SPK@@YAXAAVParticle@1@0@Z) で参照function "private: void __thiscall SPK::Pool::swapElements(class SPK::Particle &,class SPK::Particle &)" (?swapElements@?$Pool@VParticle@SPK@@@SPK@@AAEXAAVParticle@2@ 0@Z) main.obj : エラー LNK2001: 未解決の外部シンボル "unsigned int SPK::randomSeed" (?randomSeed@SPK@@3IA) main.obj : エラー LNK2001: 未解決の外部シンボル "unsigned long const SPK::NO_ID" (?NO_ID@SPK@@3KB) main.obj : エラー LNK2001: 未解決の外部シンボル "public: static float const * const SPK::Transformable::IDENTITY" (?IDENTITY@Transformable@SPK@@2QBMB)

これらのエラーを生成したコードは次のとおりです。

#include "Extensions/Emitters/SPK_RandomEmitter.h"

using namespace SPK;

int main()
{   
    RandomEmitter e;
    e.changeFlow(6);
    e.getFlow();
    return 0;
}

それが私の問題です。説明が多すぎて申し訳ありませんが、解決策が見つからないまま 3 日間検索を行いました。

PS:

ライブラリは非常に大きいため、自動ソリューションが必須です。

4

4 に答える 4

4

PInvoke は、探していることを実行する方法です。関数のシグネチャを知っている限り、その DLL のコードを持っているかどうかは問題ではありません。

PInvoke の基本をカバーする MSDN およびコード プロジェクトの次の記事を参照してください。

  1. プラットフォーム呼び出しのチュートリアル
  2. P/Invoke チュートリアル: 基本 (パート 1)

編集: DllImport 署名を生成できるツールがあります。私はこれらを自分で試したことはありません。見てください:

  1. P/Invoke シグネチャ ジェネレータ
  2. P/Invoke コードを生成する最も簡単な方法は?
  3. これです
  4. http://www.swig.org/

それが役立つことを願っています。

于 2014-11-18T04:47:36.680 に答える