일단 소스 확인해 봤습니다.
문제는 Record 구조체 선언부 때문 인것 같네요.
C의 Struct 구조와 delphi 의 Record 구문은 다른 방식으로 처리를 하는것 같습니다.
Delphi는 기본적으로 속도 문제로 Compiler 옵션을 보면 Record field alignment가 8Bytes 인가로 설정이 되어
레코드를 해당 값으로 맞춰서 메모리가 할당 됩니다.
그래서 메모리 영역 충돌이 일어나서 에러가 발생한 것 같습니다.
참고 >
http://www.delphibasics.co.uk/RTL.asp?Name=Packed
InfraIDScan.pas 에 선언된 Record 부분을 모두 변경해야 합니다.
Record ==> Packed record
unit InfraIDScan;
interface
const
TRUECOLOR_MODE = 3;
GRAY_MODE = 2;
HALFTONE_MODE = 1;
BW_MODE = 0;
FORMAT_BMP = 0;
FORMAT_TIFF = 1;
FORMAT_JPG = 2;
type
ScannerAbility = packed record ///<--- record 를 모두 packed record 로 변경
VendorName : Array [0 .. 11] of BYTE;
ModelName : Array [0 .. 19] of BYTE;
DriverVersion : Array [0 .. 7] of BYTE;
PortType : Array [0 .. 11] of BYTE;
PortAddress : Array [0 .. 7] of BYTE;
MaxScanWidth : Word;
MaxScanLength : Word;
OpticalRes : Word;
MaxXResolution: Word;
MaxYResolution: Word;
ButtonNumber : BYTE;
end;
수정한 샘플을 첨부합니다.
저는 델파이7을 사용중이라 델파이7에 맞게 약간 수정해서 컴파일 했습니다.
실행을 해보려고 하니 추가적인 DLL을 요구해서 실행은 못했습니다.
소스상에 별 문제는 없는 것 같고 C++ 과 Delphi의 구조체 메모리 할당 문제로 보이니
원 소스에서도 record 를 packed record로 변경만 하면 아마 실행에 문제가 없을겁니다.
수고하세요.
라미엘 님이 쓰신 글 :
: 답변달아주셔서 감사합니다. 우선 제조사에서 제공받은 샘플코드(VC++ 6.0)과 dll, 그리고 제가 테스트중인 테스트코드를 첨부합니다.
: 문제가되는 dll파일 : BKV3.dll
: 제조사 제공 소스(VC) : Sample_Program.zip
: 제가 테스트중인 소스(delphi2009) : idScan.zip
: idScan.zip을 실행 가능한 소스로 만들어야하는데 잘안됩니다. idScan프로젝트를 열면 InfraIDScan.pas파일에서 dll을 읽어와서 사용할수있도록 하려고 하는데 델파이를 시작한지 얼마되지않아 잘안됩니다. 도움을 주시면 감사하겠습니다.
:
: DigitalNomad 님이 쓰신 글 :
: : 널문자는 없어도 되는데 혹시나 해서 추가한 것입니다.
: :
: : 그렇게 복잡한 DLL 함수는 아닌것 같은데 장비가 없으니
: : 정상 작동 여부까지는 알수가 없네요..
: : 초기화쪽에 문제가 있으서 그런가..
: :
: : 일단 제조사에서 받으신 샘플 프로그램과 DLL등 테스트 프로그램을 올려줘 보세요.
: : 델파이쪽 프로그램도 테스트 프로그램 전체 소스를 올려줘 보시구요..
: :
: : 한번 확인해 보겠습니다.
: :
: :
: : 라미엘 님이 쓰신 글 :
: : : 같은 에러가 나네요... PAnsiChar로 선언된 매개변수에 PAnsiChar()로 캐스팅해 넘기면 마지막에 널문자가 들어가지 않아서 문제가 될까요? 장비제조사에서 받은 샘플 프로그램에서는 BK_ScanToBMPFile() 프로시져를 콜하면 바로 장비가 작동하는데 저는 BK_ScanToBMPFile()을 호출하면 약 4~5초간 프로그램이 응답없음이 되다가 그후 result :='스캔실패';로 넘어가 실행되고 바로 Access Violation이 발생합니다. 제가 직접 dll을 컨트롤 하는것이 처음이라 너무 힘들어요... 혹 전체 소스와 dll을 올리면 도움주실수 있을까요? 원래 제가 델파이 파트가 아닌데 어쩌다가 델파이를 하게되어 요즘 부족함을 많이 느끼고 있습니다... 도와주세요.
: : :
: : :
: : : DigitalNomad 님이 쓰신 글 :
: : : : DLL 헤더 선언부와 델파이 소스를 살펴보니 선언부는 문제는 없어 보이는데요..
: : : : 다음과 같이 한번 바꿔서 해보세요.
: : : :
: : : : BKV3_API int WINAPI BK_ScanToBMPFile(char *upperName, char *bottomName);
: : : :
: : : : //델파이 소스
: : : :
: : : : function BK_ScanToBMPFile(upperName:PAnsiChar; bottomName:PAnsiChar):integer cdecl; external 'BKV3.dll';
: : : :
: : : : procedure TForm1.Button1Click(Sender: TObject);
: : : : var FrontFilePath,
: : : : BackFilePath:AnsiString;
: : : : begin
: : : : FrontFilePath := 'aaa.jpg'+#0 ;
: : : : BackFilePath := 'bbb.jpg'+#0 ;
: : : : if BK_ScanToBMPFile(PAnsiChar(FrontFilePath),PAnsiChar(BackFilePath))<>1 then
: : : : //정상 실행되지 않아 에러체크루틴으로 들어갑니다.
: : : : begin
: : : : result := '스캔실패'; //<<====에러 메세지 출현 지점
: : : : exit;
: : : : end;
: : : : end;
: : : :
: : : :
: : : :
: : : :
: : : :
: : : :
: : : : 라미엘 님이 쓰신 글 :
: : : : : 염치불구하고 다시 질문올립니다. 아래 dll관련 파라메터 질문을 올렸는데 다른 부분에서 에러가 나서 답답한 마음에 재질문올립니다. dll개발사에서 보내준 vc6.0샘플 소스에는 dll함수를 external선언할때 char*로 파라메터를 설정했는데 델파이2009로 설정할때 PChar 또는 PAnsiChar로 설정해도 access violation에러가 납니다. 특이한 것은 델파이 자체에서 나는 에러가 아니라 dll내부에서 나는 에러같습니다. 디버깅을 하면 다음 루틴(에러확인 루틴)으로 넘어가는데 그 이후 첨부파일과 같은 메세지가 뜹니다.
: : : : : 고수님들 다시한번만 도와주세요...
: : : : :
: : : : : //VC소스
: : : : :
: : : : : #ifdef __cplusplus
: : : : : extern "C"
: : : : : {
: : : : : #endif
: : : : : BKV3_API int WINAPI BK_ScanToBMPFile(char *upperName, char *bottomName);
: : : : : #ifdef __cplusplus
: : : : : }
: : : : : #endif
: : : : :
: : : : :
: : : : : void aaaDLG::OnScan()
: : : : : {
: : : : : int rc;
: : : : :
: : : : :
: : : : : rc = BK_ScanToBMPFile((char *)(LPCSTR)m_strUpperName, (char *)(LPCSTR)m_strBottomName);
: : : : : if (rc != 1) {
: : : : : EndWaitCursor();
: : : : : sprintf(szString, "No Paper or Scan Error !, rc = %d", rc);
: : : : : MessageBox(szString, "BKV3", MB_OK);
: : : : : return;
: : : : : }
: : : : : }
: : : : :
: : : : :
: : : : : //델파이 소스
: : : : :
: : : : : function BK_ScanToBMPFile(upperName:PAnsiChar; bottomName:PAnsiChar):integer cdecl; external 'BKV3.dll';
: : : : :
: : : : :
: : : : : procedure TForm1.Button1Click(Sender: TObject);
: : : : :
: : : : : var FrontFilePath, BackFilePath:String;
: : : : : begin
: : : : :
: : : : : FrontFilePath := 'aaa.jpg' ;
: : : : : BackFilePath := 'bbb.jpg' ;
: : : : : if BK_ScanToBMPFile(PAnsiChar(AnsiString(FrontFilePath)),PAnsiChar(AnsiString(BackFilePath)))<>1 then //정상 실행되지 않아 에러체크루틴으로 들어갑니다.
: : : : : begin
: : : : : result := '스캔실패'; //<<====에러 메세지 출현 지점
: : : : : exit;
: : : : : end;
: : : : : end;
: : : : :