2011-12-29 3 views
8

OK - 나는 결코 간단한 질문이없는 것 같습니다.델파이 CopyMemory 대 C++ memcpy

C++로 작성된 사용자 정의 라이브러리 (저에게 쓰여지지는 않음)가 있습니다. 이 라이브러리는 일부 네트워크 통신을 수행하고 바이트 배열로 일부 데이터를 전달하고 반대쪽에서 바이트 배열을 검색합니다. 라이브러리는 클라이언트/서버와의 데이터 송수신에 대한 모든 네트워크 물건을 처리합니다.

예를 들어 클라이언트와 서버를 작성할 수 있습니다. 클라이언트에서 바이트 배열을 생성하고 라이브러리는 바이트 배열을 받아서 서버로 보냅니다. 필자가 작성한 서버는 동일한 라이브러리를 사용하여 역순으로 처리합니다. 즉, 모든 트래픽 수신을 처리하고 결국 바이트 배열을 다시 전달합니다.

라이브러리는 다음과 같이 구조체의 일부로 바이트 배열을 정의합니다 ... (라이브러리를 델파이에서 정적으로로드하고 있지만 차이는 있지만, FastMM4를 사용하고 있습니다. 내가 확인을해야 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에서

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

... 응답 ++ 클라이언트는

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

은 그래서 에세이 후, 나는 생각 ...는 C++ 서버 나 서버에이 데이터를 수신와 통신 C++에서 클라이언트를 작성하면 올바르게 통신 할 수 있기 때문에 C++ 서버 코드가 올바르지 만 C++ 클라이언트를 델파이로 작성된 클라이언트로 바꾸는 것은 작동하지 않습니다. 내가 같은 일을했지만 어떻게 든 내 바이트 배열는 C++ 서버에 도달 할 때까지는 다른 생각에서 CopyMemory와 방어 적이기를 교체했습니다 ... 내 델파이 클라이언트는 그래서 다음 ...

// 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' 

않습니다 ('72 101 108 108 111 ')

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

는 내가 뭔가 잘못하고있는 중이 야 의심이되는 델파이 클라이언트에서 데이터가 올바른 나타나지만 서버에서받은 데이터는 "안녕하세요"어떻게 든 ... 잘못 CopyMemory ...? 아니면 내가 exe와 dll 사이에 메모리 공유 잘못있어? C++ 네트워킹 라이브러리가 사용하는 메모리 모델의 종류를 어떻게 알 수 있습니까? 아니면 방금 바이트 배열을 잘못 복사 했습니까? 어떤 도움 훨씬

+1

저는 DLL에 대해 오해하고 있다고 생각합니다. EXE와 DLL 사이에는 "메모리 공유 모델"이 없습니다. 동일한 주소 공간에서 실행됩니다. 포인터를 앞뒤로 전달할 수 있으며 EXE 또는 DLL 중 하나를 제한없이 읽고 쓸 수 있습니다. 그러나 특정 DLL은 특정 인터페이스에 따라 매개 변수를 복사해야 할 수도 있습니다. 귀하의 경우 누가 'content.data'를위한 공간을 할당합니까? 초기화되지 않은 포인터에 의해 결정되는 임의의 공간에 데이터를 복사하고 있습니까? –

+1

시도 CopyMemory (lContentPointer, @ByteArray [0], 5); – ComputerSaysNo

+0

C 문자열에 * 마지막 제로 바이트를 복사하는 것을 잊었다 고 생각합니다. 예 : memcpy ((void *) content.data(), data, strlen (data) +1); C 문자열 규칙은 문자열을 0 바이트로 끝내야한다는 것입니다. 파스칼 (아마도 델파이, 나는 모르겠다)은 다른 규약 (예 : 길이를 나타내는 단어로 문자열을 시작하는 것)을 가질 수 있습니다. 'CopyMemory'와 관련된 질문에 답변 할 수 없습니다. –

답변

12
CopyMemory(lContentPointer, @ByteArray, 5); 

오류가 ByteArray 어레이의 첫 번째 요소의 포인터는 효과적으로 있다는 ... 알. 따라서 포인터의 주소를 배열의 첫 번째 요소에 전달합니다. 즉, 추가, 가짜, 간접적 인 수준이 있습니다.당신은 전자는 Win32 API 함수이고, 후자는 C 표준 라이브러리 함수,

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

또는 memcpyCopyMemory에 관해서는

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

이 필요합니다. 두 기능은 동일한 작업을 수행하며 서로 바꿔서 사용할 수 있습니다.

+0

고마워 데이비드 ... 내 게시물에 2 주에 2 번 대답 해보십시오. – 0909EM

+0

@ 0909EM 네, 그는 여기 델피의 능동적 인 전문가입니다. +1 –

+0

@Seth 많은 사람 중 하나입니다 ;-) –