2011-09-26 3 views
3

2 부분의 응용 프로그램 인 Delphi와 C가 있는데 질문이 두 개 있습니다. 1. 매개 변수를 Delphi에 전달하는 가장 빠른 방법은 무엇입니까? Delphi/C로 전달하는 매개 변수가 더 빠름

  1. procedure name(Data: string); // Data is Copied to another location before passing so its slow 
    procedure name(var Data: string); // Data is Passed by pointer, Faster 
    procedure name(const Data: string); // unknown 
    
    내가 C의 포인터가 전달 파라미터 싶어 난 싶어 전체 배열을 전달 그것의 제 1 부분을 절단하고, 나머지

    통과하지 못한 문자 배열과 기능을 가지고
    void testfunction(char **Data) 
    { 
        printf("Data = %d\n", *Data); 
        return; 
    } 
    
    int main() 
    { 
        char Data[] = "TEST FUNCTION"; 
        testfunction(&&Data[4]);  // Error 
        return 0; 
    } 
    

감사

+1

문자열 데이터를 C DLL에서 Delphi로 전달해야하는 경우 LPCSTR (char *) 및 LPWSTR (wchar_t *)과 동일한 델파이 인터페이스에서 PAnsiChar 또는 PWideChar 유형을 사용하십시오. –

+1

@Warren'LPCSTR'은 실제로'const char *'입니다. 일반적으로'LPSTR'과'LPWSTR' 또는'LPCSTR'과'LPCWSTR'을 조합합니다. –

+1

맞습니다. 나는 더 이상 그 주석을 편집 할 수 없으므로 그 점을 지적 해 주셔서 감사합니다. –

답변

6

델파이 문자열은 힙에 상주하며 항상 포인터로 전달됩니다. 값을 통한 첫 번째 전달 예제가 올바르지 않습니다. 값으로 전달 된 문자열은 복사되지 않습니다. 참조 만 복사됩니다. 문자열 복사에는 마법 복사 (copy-on-write) 동작이 있기 때문에 가능합니다. 값으로 전달 된 동적 배열이 복사됩니다.

컴파일러가 참조 계산 코드를 최적화 할 수 있기 때문에 문자열 전달시 const를 사용하면 성능이 가장 좋습니다.

C 코드는 다소 혼란 스럽습니다. char**을 원하지 않고 char*을 원합니다. C 문자열 인 char*은 null로 끝나는 메모리 블록에 대한 포인터 일뿐입니다. 이미 포인터이므로 C 문자열에 대한 포인터를 가져올 필요가 없습니다.

그리고 %d이 아니라 %s을 의미합니다. 다섯 번째 문자에서 시작하는 C 문자열을 전달하려면 Data+4을 작성하십시오.

void testfunction(char *Data) { 
    printf("Data = %s\n", Data); 
} 

int main() { 
    char Data[] = "TEST FUNCTION"; 
    testfunction(Data+4); 
    return 0; 
} 
+0

예, % s을 (를) 의미했습니다. 죄송합니다.이 또한 C에 불평합니까? 내 말은 char *를 전달하고 함수 안에서 수정하는 것은 delphi와 동일하다는 뜻입니까? – killercode

+1

@killercode C 문자열은 Delphi 문자열과 완전히 다릅니다. C에서는 버퍼를 직접 관리해야합니다. C 문자열 내에서 문자를 수정할 수 있지만 C에서'var s : string'과 동등한 것을 원한다면 실제로'char ** '를 사용할 것입니다. 그러나 이전 문자열을 할당 해제하고 새 문자열을 다시 할당해야합니다 (확장해야하는 경우). 참조 계산 등이 없습니다. 당신이 수정하지 않았기 때문에'char *'를 사용했습니다. 이것은 사람들이 C가 아닌 C++를 사용하는 많은 이유 중 하나입니다. –

+0

델파이에서 가장 빠르지 만 const입니까? – killercode

2

코드는 것 같아요 오해의 소지가 조금있다. "FUNCTION"만 인쇄하려고합니까? 그럴 경우 :

그러면 해당 함수의 문자열이 배열의 인덱스 4 (포함)에서 나머지 부분까지 전달됩니다. char *를 전달하면 해당 함수의 로컬 스택에 문자열이 복사되지 않습니다. 그 메모리의 시작 부분에 대한 포인터.

1

난 단지 델파이 부분에 응답 할 수 있습니다 (내 C는 지금 조금 녹슨와 C 포인터/배열 참조 내 머리를 다치게 할 때 I 오전 현재 날짜까지)

문자열은 포인터이며 항상 참조로 전달되므로 데이터는 -EVER를 전달할 때 복사되지 않습니다.

그러나,

procedure test(s:String); 

의 경우 포인터 S가 전달되고 프로 시저 테스트 내부 S를 수정하는 경우, 고유 한 문자열 생성 및 S에 할당 된 새 포인터가 아니라한다 원래 전달 된 변수. 당신은 파리 (S + '어쩌구 어쩌구 저쩌구')

procedure test(var s: String); 

포인터 S의 주소가 전달됩니다

포인터 S가 전달에 수정/문자열 litterals 및 문자열 표현을 전달하고 경우 수 프로 시저 테스트 내에서 S를 수정하고, 고유 한 문자열이 생성되며 (필요한 경우) 새 포인터가 S에 할당되고 원래 전달 된 변수가 반환됩니다.당신은 즉석에서 수정 된 문자열 litterals 및 문자열 식/통과 할 수 없다 (S + '를 즐 즐 즐')

procedure test(const s: string); 

포인터 (S)가 전달되고, 당신은 프로 시저 테스트 기간 안에 S를 수정할 수 없습니다. (좋아, 당신은 주위에 나사와 컴파일러를 바보하지만 할 추한 하드이며 일반적으로 타입 캐스팅을 많이 필요로 할 수 있습니다)

+0

좀 더 복잡합니다. string.dify 문자열을 수정하지 않아도 값에 의한 일반 패스에는 참조 횟수 오버 헤드가 있습니다. const를 사용하면이를 피할 수 있습니다. –

+0

@David Heffernan -> 아 그래, 나는 그들이 기억 가치를 증가시키는 것을 잊었다. 그래도 질문자가 생각한 전체 사본보다 훨씬 적습니다. –

+0

그래, 발생하지 않는 전체 사본보다 적습니다! ;-) 값으로 평야와 상수 사이의 차이가 중요한 경우 나는 놀라게 될 것이다. –

3

아무도 잘 알려진 사실을 강조하지 않았다을 델파이 2009, string = UnicodeString 이후 따라서 PWideChar/LPCWSTR이 아닌 PChar/LPCSTR으로 내보내집니다. IMHO에 주목할 가치가 있습니다. 마음에 들지 않으면 혼란스럽고 코드가 모든 버전의 Delphi에서 작동 할 것입니다. 당신이 C 라이브러리에서 문자열 내용을 수정 하려면

, 당신은 아마도 대신 stringWideString 델파이 유형을 사용해야합니다. WideString은 Windows에서 할당되고 처리됩니다 (COM/Ole 문자열). OLESTR 포인터를 처리 할 수있는 모든 해당 C API가 있습니다. 그리고이 WideString은 Delphi 2009 유니 코드 중단 (Unicode가 항상 발생했습니다)으로 인해 어려움을 겪지 않습니다. 물론

, WideStringstring가 (여러 가지 이유로, 주요 하나 WideString에 대한 훨씬 느린 힙 할당입니다 - 비스타 이후 점점 나아지고는)보다 느린이지만, 이럴 일부 텍스트 데이터를 내보내는의 안전한 교차 언어 방법 Delphi 응용 프로그램과 라이브러리 (Windows 환경)를 오가는 데 사용됩니다. 예를 들어 .Net 세상에서는 변수 OLESTR을 정렬하는 것이 좋습니다.

관련 문제