Delphi Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
델파이 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
FreePascal/Lazarus
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

델파이 Q&A
Delphi Programming Q&A
[15602] Re:Re:DLL함수호출시 구조체 파라미터에관하여 질문드립니다.
눈팅이 [songy1] 1774 읽음    2015-12-04 18:07
우선 답변 정말 감사드립니다.

제가아무래도 질문글을 난해하게 썻나봅니다. 말씀하신대로 저도 아래와같이 이미 시도해 보았습니다.

PEpdBuf = ^TEpdBuf ;
TEpdBuf = array[0..32767] of SmallInt;

TRecognition_Result_ENG = record
  ...
   EpdBuf: PEpdBuf;
end;

허나 DLL에서 해당 배열을 동적배열로 다루기때문에 Dll에서 초기화하는과정에서 엑세스 바이얼레이션 에러가 일어납니다.
그래서 말씀하신대로 델파이에서의 동적배열(array of ...)이 호환이 안되는 것인지 확인하기위해서 임의로 해당 구조체를 받아 처리하는 테스트 DLL을 VC++로 작성하여 테스트 해 보았고 정상적으로 처리가 되는것을 확인했습니다.(질문글 맨 아래  "****임의 테스트용 Dll코드와 델파이코드")

kylix 님이 쓰신 글 :
: VC++ DLL과 인터페이싱하는데 델파이 고유의 자료형인 동적배열(array of ...)을 사용하니 문제가 생기는 겁니다.
:
: VC코드에 있는것처럼 델파이에서도 정적배열(array[0..최대값] of SmallInt)의 포인터를 사용하세요. VC코드처럼 DLL함수 호출하기 전에 메모리할당하시구요. 다 쓴뒤에도 메모리 해제하시구요.
:
: 눈팅이 님이 쓰신 글 :
: : 업체에서 dll을받아 VC용샘플을 델파이로 변경하여 진행하고있는데 알 수없는 런타임 에러가 발생하고있어 헤메고있습니다.
: : 아무래도 메모리상에서 뭔가 꼬이면서 발생하는것 같은데 해결법을 모르겠습니다.. ㅠㅠ
: :
: : DioSTT_Edu_ENG_Get_Score 라는 함수를 실행하고나면 문제가 발생하는데.. 요것이 하는일이 RECOGNITION_RESULT_ENG구조체를 레퍼런스 파리미터로받아
: : 해당구조체에 값을 채워주는식입니다. 그냥 해당함수만 실행시키고나면 별 문제없는데.. 해당함수실행뒤 채워진값을가지고 뭔가를 하면 그때부터 문제가 생겨버립니다.
: : (구조체안에 데이터는 정상적으로 들어와있습니다.)
: :
: : 짐작되는 부분은 구조체내의 EPD_Buf넘이 smallint형 동적배열인데 요넘에게 Dll함수가 배열원소들을 채워서주게되고나서
: : 델파이에서 구조체의 끝점을 찾지못해 발생하는 문제가 아닌가 짐작됩니다...
: :
: : 아무래도 레코드부분 선언을 제가 잘못한것같은데 뭔지를 모르겠습니다. 업체에도 물어 볼 수도 없는것이.. 업체는 델파이가 뭔지도 모르고 있습니다.ㅡ.ㅡ;;
: :
: : ※참고로 제가 VC++로 임의Dll을 만들어서 해당 구조체를 가지고 EPD_Buf에 값을 넣어서 리턴 해 보았는데 제가 임의로 만들어서 테스트 해본넘은 문제가 없었습니다..
: : 하지만 제 테스트용 과 업체측 제공 dll에서의 EPD_Buf에 데이터를 넣어주는 방식이 틀린지 디버깅걸어보면 업체측Dll에서는 [0]42,[1]35,[2]55.. 이런식인데
: : 제 테스트용 dll에서 넣어준 데이터는 실제 디버깅에서는 찾지는못하고 찍어보면 값이 정상적으로 나옵니다.
: :
: : **** VC 코드
: :
: : #ifdef WIN32
: : #define __decls_dllexport__ __declspec(dllexport)
: : #ifdef __cplusplus
: : #define DIOSTT_EDU_ENG_API extern "C" __declspec(dllexport)
: : #else
: : #define DIOSTT_EDU_ENG_API __declspec(dllexport)
: : #endif
: :
: : #define L_ENG_MAX_LIST_CNT            (4096-1) // 최대 리스트 수
: : #define L_ENG_MAX_LIST_LEN            128  // 리스트 하나의 최대 길이
: : #define L_ENG_MAX_WORD_LEN            32  // 한 단어의 최대 길이
: : #define L_ENG_MAX_WORD_CNT            128 // 한 문장내 단어의 최대 수
: : #define L_ENG_MAX_RESULT_CNT        10
: :
: : typedef struct RECOGNITION_RESULT_ENG
: : {
: :     int nInputLevel;
: :     int nInputProfile;
: :     int nInputPauseThreshold;
: :     int iTextForm;
: :     char szInputText[L_ENG_MAX_LIST_CNT*L_ENG_MAX_LIST_LEN];
: :     int result_cnt;
: :     char result_string[L_ENG_MAX_RESULT_CNT][L_ENG_MAX_LIST_LEN];
: :     int result_score[L_ENG_MAX_RESULT_CNT];
: :     int total_score;
: :     int word_cnt;
: :     char word[L_ENG_MAX_WORD_CNT][L_ENG_MAX_WORD_LEN];
: :     int word_score[L_ENG_MAX_WORD_CNT];
: :     int word_position[L_ENG_MAX_WORD_CNT][2];
: :     char phoneme_in_word[L_ENG_MAX_WORD_CNT][L_ENG_MAX_WORD_LEN];
: :     char phoneme_cnt_in_word[L_ENG_MAX_WORD_CNT];
: :     int phoneme_score_in_word[L_ENG_MAX_WORD_CNT][L_ENG_MAX_WORD_LEN];
: :     int phoneme_position_in_word[L_ENG_MAX_WORD_CNT][L_ENG_MAX_WORD_LEN];
: :     int word_stress[L_ENG_MAX_WORD_CNT];
: :     unsigned char bEPD; // 1: EPD_OK, 0: EPD_FAIL
: :     int EPD_position[2];
: :     int wpm;
: :     char nSNR;
: :     int EPD_sample_cnt;
: :     short* EPD_Buf;
: :
: : #ifdef __cplusplus
: :     __decls_dllexport__ RECOGNITION_RESULT_ENG();
: :     __decls_dllexport__ ~RECOGNITION_RESULT_ENG();
: :     __decls_dllexport__ void setEPDBuffer(short *buff, int sampleCount);
: :     __decls_dllexport__ void clearEPDBuffer();
: : #endif
: :
: : }Recognition_Result_ENG;
: :
: : DIOSTT_EDU_ENG_API int DioSTT_Edu_ENG_Get_Score(Recognition_Result_ENG *pScore);
: :
: :
: :
: : **** 델파이 2010 코드
: : const
: :   L_ENG_MAX_LIST_CNT = (4096 - 1);
: :   L_ENG_MAX_LIST_LEN = 128;
: :   L_ENG_MAX_WORD_LEN = 32;
: :   L_ENG_MAX_WORD_CNT = 128;
: :   L_ENG_MAX_RESULT_CNT = 10;
: :
: : type
: :   TEpdBuf = array of SmallInt;
: :   PEpdBuf = ^TEpdBuf;
: :
: :   PRecognition_Result_ENG = ^TRecognition_Result_ENG;
: :   TRecognition_Result_ENG = record
: :     nInputLevel: integer;
: :     nInputProfile: integer;
: :     nInputPauseThreshold: integer;
: :     iTextForm: integer;
: :     szInputText: array [0..L_ENG_MAX_LIST_CNT * L_ENG_MAX_LIST_LEN - 1] of ansichar;
: :     result_cnt: integer;
: :     result_string: array [0..L_ENG_MAX_RESULT_CNT - 1, 0..L_ENG_MAX_LIST_LEN - 1] of ansichar;
: :     result_score: array [0..L_ENG_MAX_RESULT_CNT - 1] of integer;
: :     total_score: integer;
: :     word_cnt: integer;
: :     word: array [0..L_ENG_MAX_WORD_CNT - 1, 0..L_ENG_MAX_WORD_LEN - 1] of ansichar;
: :     word_score: array [0..L_ENG_MAX_WORD_CNT - 1] of integer;
: :     word_position: array [0..L_ENG_MAX_WORD_CNT - 1, 0..1] of integer;
: :     phoneme_in_word: array [0..L_ENG_MAX_WORD_CNT - 1, 0..L_ENG_MAX_WORD_LEN - 1] of ansichar;
: :     phoneme_cnt_in_word: array [0..L_ENG_MAX_WORD_CNT - 1] of ansichar;
: :     phoneme_score_in_word: array [0..L_ENG_MAX_WORD_CNT - 1, 0..L_ENG_MAX_WORD_LEN - 1] of integer;
: :     phoneme_position_in_word: array [0..L_ENG_MAX_WORD_CNT - 1, 0..L_ENG_MAX_WORD_LEN - 1] of integer;
: :     word_stress: array [0..L_ENG_MAX_WORD_CNT - 1] of integer;
: :     bEPD: byte;
: :     EPD_position: array [0..1] of integer;
: :     wpm: integer;
: :     nSNR: ansichar;
: :     EPD_sample_cnt: integer;
: :     EPD_Buf: TEpdBuf; // <--동적 배열입니다.
: :     //EPD_Buf: PEpdBuf;
: :     //EPD_Buf: PSmallInt;
: :   end;
: :
: :
: :   function DioSTT_Edu_ENG_Get_Score(var UserResult: TRecognition_Result_ENG): integer; stdcall; external 'DioSTT_Edu_ENG.dll';
: :   //function DioSTT_Edu_ENG_Get_Score(pUserResult: PRecognition_Result_ENG): integer; stdcall; external 'DioSTT_Edu_ENG.dll';
: :
: :
: : **** 델파이 2010 실행코드
: : procedure TFormMain.ENG_GetScore;
: : var
: :   uRet: TRecognition_Result_ENG;
: :   fs: TFileStream;
: : begin
: :   uRet.EPD_Buf := nil;
: :   DioSTT_Edu_ENG_Get_Score(uRet); //요기까지만 실행하면 문제없습니다.
: :  
: :   //Memo1.Lines.Add('dd'); //<<-- 하다못해 메모에다 아무메세지만찍어도 런타임 에러가 납니다.
: :
: :   if FileExists(FEPDFile) then
: :     fs := TFileStream.Create(FEPDFile, fmOpenReadWrite or fmShareDenyNone)
: :   else
: :     fs :=TFileStream.Create(FEPDFile, fmCreate);
: :
: :   try
: :     fs.Position := 0;
: :     fs.WriteBuffer(uRet.EPD_Buf[0], uRet.EPD_sample_cnt * 2); // <-- EPD_Buf의 값은 정상적으로 들어와서 파일저장까지된 후 런타임 에러가 납니다.
: :   finally
: :     fs.Free;
: :   end;
: :
: : end;
: :
: :
: : **** 임의 테스트용 Dll코드와 델파이코드
: : - dll 코드
: : extern "C" __declspec(dllexport)
: : int TestApi(Recognition_Result_ENG *pScore) {
: :
: :     pScore->nInputLevel = 10;
: :     pScore->nInputProfile = 15;
: :     pScore->nInputPauseThreshold = 25;
: :     pScore->iTextForm = 35;
: :     strcpy(pScore->szInputText, "babo");
: :     pScore->EPD_sample_cnt = 23454;
: :
: :     pScore->EPD_Buf = (short *)malloc(sizeof(short) * 23454);
: :     for (short i = 0; i < pScore->EPD_sample_cnt; i++) {
: :         pScore->EPD_Buf[i] = i;
: :     }
: :
: :     return 1;
: : }
: :
: :
: : - 델파이코드
: : function TestApi(var UserResult: TRecognition_Result_ENG): integer; stdcall; external 'testdll.dll';
: : procedure TFormMain.Button1Click(Sender: TObject);
: : var
: :   i, nResult: integer;
: :   uRet: TRecognition_Result_ENG;
: : begin
: :   uRet.EPD_Buf := nil;
: :   nResult := TestApi(uRet);
: :
: :   Memo1.Lines.Add(IntToStr(nResult));
: :   Memo1.Lines.Add(IntToStr(uRet.nInputLevel));
: :   Memo1.Lines.Add(IntToStr(uRet.nInputProfile));
: :   Memo1.Lines.Add(IntToStr(uRet.nInputPauseThreshold));
: :   Memo1.Lines.Add(IntToStr(uRet.iTextForm));
: :   Memo1.Lines.Add(uRet.szInputText);
: :   Memo1.Lines.Add(IntToStr(uRet.EPD_sample_cnt));
: :   for i:=0 to 23453 do begin
: :     Memo1.Lines.Add(IntToStr(uRet.EPD_Buf[i]));
: :   end;
: :
: : end;
: :

+ -

관련 글 리스트
15600 DLL함수호출시 구조체 파라미터에관하여 질문드립니다. 눈팅이 1716 2015/12/04
15601     Re:DLL함수호출시 구조체 파라미터에관하여 질문드립니다. kylix 1771 2015/12/04
15602         Re:Re:DLL함수호출시 구조체 파라미터에관하여 질문드립니다. 눈팅이 1774 2015/12/04
15603             Re:Re:Re:DLL함수호출시 구조체 파라미터에관하여 질문드립니다. kylix 2343 2015/12/04
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.