2011-12-29 109 views
8

OK - 私は決して簡単な質問をしていないようです。Delphi CopyMemory対C++ memcpy

私はC++で書かれたカスタムライブラリ(私によって書かれていない)を持っています。このライブラリはいくつかのネットワーク通信を行い、私はバイト配列としてそれにいくつかのデータを渡し、反対側でそれからバイト配列を取り出します。ライブラリは、クライアント/サーバとの間でデータの送受信を行うすべてのネットワークの処理を行います。

たとえば、クライアントとサーバーを作成できます。私はバイト配列を生成するクライアントから、ライブラリはバイト配列をとり、それをサーバに送ります。私が書いたサーバは、同じライブラリを使用して逆を行います。つまり、すべての受信トラフィックを処理し、最終的にバイト配列を返します。

ライブラリは、次のように構造体の一部としてバイト配列を定義しています...(私はDelphiでライブラリを静的にロードしていますが、違いはないと思いますが、FastMM4を使用しています私はOKであるべきFastMMを使用して承知している限り?アプリとDLLとの間のメモリ共有モデルに影響を与えるとして、また「私が送信しようとしています私のクライアントから、

struct content { 
    void *data; 
    int size; 
} 

とにかく無駄)にShareMemを試してみましたこんにちは "...受け入れられた知恵は、memcpyを使ってバイト配列データがこの構造体にコピーされるということです...

char *data = "Hello"; 
memcpy((void *)content.data(), data, strlen(data)); // last parameter is length, ie 5 
// network.sendrequest(content); 
// where content.data() returns the aforementioned pointer 

私のサーバー上では「World」と返信します。以下のようにサーバがだからエッセイた後、私は思う...私は、サーバー上でこのデータを受信C++サーバーとの通信C++クライアントから...

0x0035fdf6 "Hello" (or in Bytes... 72, 101, 108, 108, 111) 

char *data = "World"; 
memcpy((void *)content.data(), data, strlen(data)); // last parameter is length, ie 5 
// network.sendreply(content); 

を返信します私はC++でクライアントを書くと正しく通信できるので、C++のサーバコードは正しいです...しかし、C++クライアントをDelphiで書かれたクライアントに置き換えることはできません。私はそう...

// lDataPointer is a retrieved reference to the 
// pointer (void *data; see above) defined in the 
// C++ library. It appears to be a valid pointer at runtime... 
lContentPointer := content.data(); // from DLL 
// Where ByteArray is populated with byte data of "Hello" 
CopyMemory(lContentPointer, @ByteArray, 5); // Copy from Exe to DLL 
// network.sendrequest(lContentPointer); 

// I have printed the byte array before the CopyMemory to check 
// its contents before sending, which is '72 101 108 108 111' 

を私のDelphiのクライアントは、次の処理を行い...私は同じことをしたと思ったが、何とか私のバイト配列は、それがC++サーバーに到達した時点で異なっているCopyMemory、とのmemcpyを交換しましたDelphiのクライアントからのデータが正しい表示されますが、データはサーバー上に受信間違っている...どういうわけか「こんにちは」('72 101 108 108 111' )私はと間違って何かをやっている疑いがある

0x003efd96 "h,H" (or in Bytes 104, 19, 44, 2, 72) 

なりコピーメモリ...?または、私はexeとdllの間でメモリを誤って共有してしまったのですか? C++ネットワーキングライブラリが使用するメモリモデルの種類を知るにはどうすればよいですか?または、私はそのバイト配列を間違ってコピーしたことがありますか?感謝すべてのヘルプ...

+1

私はあなたがDLLについて何か誤解していると思うかもしれません。 EXEとDLLの間には「メモリ共有モデル」はなく、同じアドレス空間で実行されます。ポインターを前後に渡すことができ、EXEまたはDLLのいずれかを制限なく読み書きすることができます。ただし、特定のDLLによって、特定のインターフェイスに応じてパラメータをコピーする必要が生じる場合があります。あなたの場合、誰が 'content.data'のスペースを割り当てますか?あなたはおそらく、初期化されていないポインタによって決まるランダムな空間にあなたのデータをコピーしていますか? –

+1

try CopyMemory(lContentPointer、@ByteArray [0]、5); – ComputerSaysNo

+0

Cの文字列に*最後のゼロバイト*をコピーするのを忘れたと思います。例えば。 memcpy((void *)content.data()、data、strlen(data)+1); C文字列の規約では、文字列をゼロバイトで終了する必要があります。パスカル(おそらくデルファイ、私には分かりません)では、違う慣習(例えば、長さを与える単語で文字列を始めるなど)があるかもしれません。 'CopyMemory'に関連する質問にはお答えできません。 –

答えて

12
CopyMemory(lContentPointer, @ByteArray, 5); 

エラーがByteArrayが、効果的に、配列の最初の要素へのポインタであるということです。このようにして、ポインタのアドレスを配列の最初の要素に渡します。言い換えれば、余分な、間違った、間接指示のレベルがあります。あなたは、前者はWin32 API関数であり、後者はC標準ライブラリ関数で、memcpyCopyMemoryについては

CopyMemory(lContentPointer, @ByteArray[0], 5); 

または

CopyMemory(lContentPointer, Pointer(ByteArray), 5); 

を必要としています。 2つの機能は同じタスクを実行し、交換可能です。

+0

デイビッドありがとうございました...私の投稿に答えたのは2週間で2回だと思います。 – 0909EM

+0

@ 0909EMはい、彼はここのデルファイの専門家です+1 + –

+0

@Seth –