0

次のようなコードがあります。

extern "C" __declspec(dllexport)  myInterface(int id, void** pFunction)
{
   ...
}

呼び出し元が pFunction ポインターを介してこの関数を使用できるように、void** pFunction 引数が関数を指すようにする必要があります。この関数は DLL を介して呼び出されます。この方法では実行したくありませんが、多くの理由から選択の余地がありません。COMがこのために作られていることは知っていますが、使用できません。理由は管理にあります。

現時点では、これを行う方法がわかりません。私がやろうとしたことはすべて、キャストの問題を引き起こします。どうすればこれを行うことができるか誰にも分かりますか? これが不明な場合は、さらに投稿できます。

ありがとう。

4

5 に答える 5

3

「myInterface」の実装を見ている場合は、次のことが必要になる場合があります。

switch (id)
{
case FUNC_1:
    *pFunction = (void *)first_function;
    break;
...
}

関数を呼び出して関数へのポインターを渡そうとする場合は、次のようになります。

void *vp = (void *)the_function_to_pass;
myInterface(1, &vp);

他に何かを考えている場合は、何を指定する必要があります。

(厳密には、C は関数ポインターがオブジェクト ポインターに割り当てられること、およびその逆が保証されないことに注意してください。ただし、POSIX はその保証を行います。同様のコメントが C++ にも当てはまると思います。)

于 2010-07-16T21:20:00.007 に答える
1

これは、標準の C または C++ で実行できるものではありません。関数ポインターが void ポインターに収まるという保証はありません (通常、C++ メンバー関数ポインターは収まりません)。つまり、関数のシグネチャを変更できない場合、標準の C や C++ でやりたいことを行うことはできず、できるという保証はまったくありません。

したがって、どのソリューションもプラットフォーム固有のものになります。質問やタグでプラットフォームを直接指定することはありませんが、私の推測では、他のものからの Visual C++ になります。

プラットフォームを具体的に指定し、渡したい関数ポインタに関する有用なものを指定してください。

于 2010-07-16T21:18:14.183 に答える
1

トリッキーですが、次のようなコードでうまくいきました。

*reinterpret_cast<void**>( &(PVOID&)( DetourFunc ) ) = (PVOID) 0x00FFFF00; 

私が理解している概念は、参照を参照し、参照を再解釈してから逆参照することです。少し混乱しますが、動作することを確認できます。右側にアドレス (&func) を入れることもできます。次の形式を使用して、DetourFunc を呼び出します。

(DetourFunc)(param, param)

元のアドレスまたは関数を呼び出します。

編集:これは機能しますが、言語のかなりの乱用のようです。ただし、機能し、他のいくつかの質問で推奨されています。

于 2010-07-16T21:37:08.310 に答える
1

Jonathan Leffler と David Thornley が述べたように、関数ポインタを変換したり元に戻したりできることは保証されていませんvoid*。移植可能な回避策は、関数ポインタを にパッケージ化し、structそのポインタを渡すことです。

void**それ自体に問題がある可能性があることに注意してください。これも回避できます。)

例えば:

typedef int (*SomeFuncType)(int);

struct FuncWrapper
{
    SomeFuncType func;
    void* output;
};

...
FuncWrapper funcWrapper;
funcWrapper.func = ...;

myInterface(id, &funcWrapper);

myInterface は次のように実装できます。

void myInterface(int id, FuncWrapper* funcWrapper)
{
    funcWrapper->func(...);
    funcWrapper->output = ...;
}
于 2010-07-16T21:39:22.583 に答える
0

みんなの助けに感謝したい。これが私がそれを少なくとも部分的に機能させる方法です。基本的に、ラッパーのアイデアは機能します。

struct myProj {virtual HRESULT __stdcall myMethod(unsigned short *&myname); };

HRESULT __stdcall myMethod(unsigned short *&myname){myname = L "myname";

return(1); }

struct myProj xProject;

それを呼び出すには:

extern "C" HRESULT __declspec(dllexport)fInterface(UINT id、LPVOID * pObj){switch(id){case FVI_ID:* pObj =&xProject; 壊す; }}

これは正しい関数を呼び出しますが、それでも問題があります。サードパーティのDLLはCStringを使用しており、CStringに含まれるいくつかのトレース関数だけでなく、他の問題も発生していると思われます。

私の本当の解決策は、comを偽造できないこと、つまりDLLをプロジェクトで使用できないことを理解する必要があることだと思います。

みんな、ありがとう。

于 2010-07-19T18:39:58.423 に答える