2011-05-02 87 views
3

我需要使用外部dll與數碼相機進行通信,並且找到了可以啓用通信的相應dll的程序。在dll描述中,我找到了適合我需求的函數。 DLL頭看起來這....如何使用DELPHI中用C語言編寫的外部DLL

//------------------------------------------------------------------- 
// ReleaseShutter() 
// Inputs: 
// timeOutInSecs timeout in secs to wait for picture to be 
//     taken and downloaded (max 60 secs) 
// pszFilename  option string in which to store the name of the 
//     saved image. Set to NULL if not required 
// numChars  length of pszFilename if defined 
// 
// Returns:// 0 - Success, image saved 
// 1 - PSRemote is not running 
// 2 - PSRemote is running but camera is not connected 
// 3 - Camera is busy 
// 4 - Timeout waiting for image to be saved 
// 5 - Error releasing shutter 
// 
// Description: 
// Take a picture and optionally wait for it to be saved to disk. 
// 
//-------------------------------------------------------------------- 
PSRemoteLIB_API int __stdcall ReleaseShutter(int timeoutInSecs, 
          char* Filename,int numChars ); 

好吧,我加載DLL,使用功能,得到結果狀態和外部程序需要的圖片,但我不能獲取文件名BACK !!!!這是我的代碼

procedure TForm1.Button2Click(Sender: TObject); 
var Status: Integer; 
Name1: PChar; 
DLLHandle: Thandle; 
TakePic: Function (T: Integer; Nam: Pchar;Num:Integer):Integer; {$IFDEF WIN32} stdcall; {$ENDIF} 

begin DLLHandle := LoadLibrary('PSRemoteLib.dll'); 
    if DLLHandle >= 32 then { success } 
    begin 
     Name1:=stralloc(1024); 
     TakePic := GetProcAddress(DLLHandle, 'ReleaseShutter'); 
     Status:=TakePic(60,Name1,SizeOf(Name1)); 
     label1.Caption:=intTostr(Status); 
     label2.Caption:=Name1; 
     FreeLibrary(DLLHandle); 
    end 
    else  MessageDlg('Error: could not find PSRemoteLib.dll', mtError, [mbOk], 0); 
    StrDispose(Name1); 
end; 

我嘗試PChar PWidechar和我在網上發現的一切,但沒有什麼!

我做錯了什麼?在隨DLL附帶的示例.exe中運行CMD模式,這工作正常!程序需要圖片和報告文件名????我有一個示例源代碼,看起來像這樣

 case 0: // success   if (filename && strlen(filename))    
{ 
       cout << "Success, image saved as: " << filename << endl;    
} 
      else    
{ 
       cout << "Success, image saved on CF card?" << endl;    
} 
      break; 
     case 1:   cerr << "PSRemote is not running" << endl; 
      break; 
     case 2:   cerr << "Camera is not connected" << endl; 
      break; 
     case 3:   cerr << "Camera is busy" << endl; 
      break; 
     case 4:   cerr << "Timeout waiting for image to be saved" << endl; 
      break; 
     default: 
      cerr << "ERROR: unexpected return status: " << status << endl;   
} 

} 
    return nRetCode; 
} 

請幫助我需要這個!

PS也DLL我也有類似的功能

{///----------------------------------------------------------------------- } 
{/// GetOutputPath() } 
{/// Inputs: } 
{/// pszPathname string in which to store the pathname of the } 
{/// directory currently being used to save images } 
{/// numChars length of pszPathname } 
{/// } 
{/// Returns: } 
{/// 0 - Success, pathname returned in pszPathname } 
{/// 1 - PSRemote is not running } 
{/// 4 - Some other error } 
{/// } 
{/// Description: } 
{/// Returns the full pathname of the directory used for saving images. } 
{/// This is the base directory as specified by SetOutputPath() plus } 
{/// any separate directories for year, month or day if selected in } 
{/// preferences. } 
{/// } 
{///----------------------------------------------------------------------- } 
var 
    GetOutputPath: function(pszPathname: PChar; 
          numChars: var Integer): SREMOTELIB_API INT __STDCALL cdecl {$IFDEF WIN32} stdcall {$ENDIF}; 

,並再次獲得狀態(整數)回來,但不是路徑名?????

+3

歡迎來到StackOverflow。這是詢問德爾福問題的好地方,但如果你(a)一次提出一個問題,(b)最好以其他人能夠搜索並找到有用的方式提問。 – 2011-05-02 18:14:04

+0

你使用的是什麼版本的Delphi? – 2011-05-02 18:15:01

回答

5

該函數想獲得char緩衝區。這意味着你必須分配這個喜歡

Name1 : array[MAX_PATH+1] of AnsiChar; 

MAX_PATH在單元的Windows定義,應該是足夠大的。 AnsiChar是所有的Delphi版本的C++ char

在你必須設置指針到緩衝區,並

Status := TakePic(60,Name1,MAX_PATH); 
+0

感謝它工作!!!!!! :) :) :) :) :) :) – snm 2011-05-02 18:48:17

2

如果我不得不猜測,我會說你使用的是Delphi 2009或更高版本。作爲Unicode轉換的一部分,PChar在D2009中的含義發生了變化。嘗試使用PAnsiChar,它應該工作。

+0

德爾福2010和再次感謝!現在工作:) – snm 2011-05-02 18:49:21

+1

如果這解決了您的問題,請接受此答案。 – johnny 2011-05-02 19:08:29

2

您已爲文件名分配空間的最大字符數呼叫的等同放着清單緩衝區,但是你已經告訴函數該緩衝區的大小不正確。您使用了SizeOf函數,該函數告訴變量的大小,而不是變量值指向的字符數。 Name1PChar,所以SizeOf(Name1)是一樣的SizeOf(PChar),這在當今總是4.你分配1024個字符,所以經過1024作爲第三個參數來ReleaseShutter

Name1 := StrAlloc(1024); 
TakePic := GetProcAddress(DLLHandle, 'ReleaseShutter') 
Status:=TakePic(60, Name1, 1024); 

如果您正在使用德爾福2009年或以後,您必須將PChar的所有用法更改爲PAnsiChar,否則您會將錯誤大小的字符類型傳遞給需要單字節字符的DLL。