2011-05-02 85 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。