如何使用 DELPHI 中用 C 编写的外部 DLL

发布于 2024-11-04 18:59:35 字数 3888 浏览 0 评论 0原文

我需要使用外部 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

微凉 2024-11-11 18:59:36

该函数想要获取一个字符缓冲区。这意味着您必须像

Name1 : array[MAX_PATH+1] of AnsiChar;

Windows 单元中定义的 MAX_PATH 一样分配它,并且应该足够大。 AnsiChar 对于所有 Delphi 版本来说相当于 C++ char

在调用中,您必须设置指向缓冲区的指针和最大字符数

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

The function wants to get a char buffer. This means you have to allocate this like

Name1 : array[MAX_PATH+1] of AnsiChar;

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

Status := TakePic(60,Name1,MAX_PATH);
苦妄 2024-11-11 18:59:36

如果我不得不猜测,我会说您使用的是 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.

猫弦 2024-11-11 18:59:36

您已为文件名缓冲区分配了空间,但您已告知函数该缓冲区的大小不正确。您使用了 SizeOf 函数,它告诉 Name1 变量的大小,而不是变量值指向的字符数。 Name1 是一个 PChar,因此 SizeOf(Name1)SizeOf(PChar) 相同,现在是总是 4. 您分配了 1024 个字符,因此将 1024 作为第三个参数传递给 ReleaseShutter

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

如果您使用的是 Delphi 2009 或更高版本,则必须更改所有对PCharPAnsiChar,否则您将向需要单字节字符的 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 the Name1 variable, not the number of characters that the variable's value points to. Name1 is a PChar, so SizeOf(Name1) is the same as SizeOf(PChar), which nowadays is always 4. You allocated 1024 characters, so pass 1024 as the third parameter to ReleaseShutter:

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

If you are using Delphi 2009 or later, you must change all your use of PChar to PAnsiChar, or else you'll be passing the wrong-sized character type to the DLL, which expects single-byte characters.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文