如何使用 DELPHI 中用 C 编写的外部 DLL
我需要使用外部 dll 与数码相机通信,我找到了具有适当 dll 的程序来实现通信。在 dll 描述中,我找到了适合我需要的函数。 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,使用函数,获取结果状态,外部程序拍照,但我无法获取文件名!!!!这是我的代码
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 附带并在 cmd 模式下运行的示例 .exe 中,这工作正常!程序拍摄图片并报告文件名???我有一个示例源代码,看起来像这样
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};
并再次获取状态(整数)但不是路径名???
I need to use external dll to communicate with digital camera and I found program with appropriate dll that enable communication.In dll description I found function that suits my needs. DLL Header Looks like this ....
//-------------------------------------------------------------------
// 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 );
Ok, I load dll, use function , get Result status and external program takes a picture but I CAN NOT GET FILENAME BACK!!!! Here is my code
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;
I try PChar PWidechar and everything that I found on net but nothing !!!
What I do wrong ???? In the sample .exe that comes with dll and runs in cmd mode this works fine !!!! Program takes picture and report filename ????I have a sample source code and looks like this
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;
}
PLEASE HELP I NEED THIS !!!
PS also in dll I have similar function
{///----------------------------------------------------------------------- }
{/// 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};
ANd again get status(integer) back but not Pathname ?????
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
该函数想要获取一个字符缓冲区。这意味着您必须像
Windows 单元中定义的 MAX_PATH 一样分配它,并且应该足够大。
AnsiChar
对于所有 Delphi 版本来说相当于 C++char
在调用中,您必须设置指向缓冲区的指针和最大字符数
The function wants to get a char buffer. This means you have to allocate this like
MAX_PATH
is defined in the unit Windows and should be big enough.AnsiChar
is for all Delphi versions the equvalent for the C++char
In the call you have to set the pointer to the buffer and the maximum number of characters
如果我不得不猜测,我会说您使用的是 Delphi 2009 或更高版本。作为 Unicode 转换的一部分,PChar 的含义在 D2009 中发生了变化。尝试使用 PAnsiChar 代替,它应该可以工作。
If I had to guess, I'd say that you're using Delphi 2009 or later. The meaning of PChar changed in D2009 as part of the Unicode conversion. Try using PAnsiChar instead and it should work.
您已为文件名缓冲区分配了空间,但您已告知函数该缓冲区的大小不正确。您使用了
SizeOf
函数,它告诉Name1
变量的大小,而不是变量值指向的字符数。Name1
是一个PChar
,因此SizeOf(Name1)
与SizeOf(PChar)
相同,现在是总是 4. 您分配了 1024 个字符,因此将 1024 作为第三个参数传递给ReleaseShutter
:如果您使用的是 Delphi 2009 或更高版本,则必须更改所有对
PChar
到PAnsiChar
,否则您将向需要单字节字符的 DLL 传递错误大小的字符类型。You have allocated space for the file-name buffer, but you have told the function an incorrect size for that buffer. You used the
SizeOf
function, which tells the size of theName1
variable, not the number of characters that the variable's value points to.Name1
is aPChar
, soSizeOf(Name1)
is the same asSizeOf(PChar)
, which nowadays is always 4. You allocated 1024 characters, so pass 1024 as the third parameter toReleaseShutter
:If you are using Delphi 2009 or later, you must change all your use of
PChar
toPAnsiChar
, or else you'll be passing the wrong-sized character type to the DLL, which expects single-byte characters.