【问题标题】:How can I use external DLL written in C from DELPHI如何使用 DELPHI 用 C 语言编写的外部 DLL
【发布时间】:2011-05-02 17:53:51
【问题描述】:

我需要使用外部 dll 与数码相机进行通信,并且我找到了具有适当 dll 的程序来启用通信。在 dll 描述中,我找到了适合我需要的功能。 DLL Header 看起来像这样....

//-------------------------------------------------------------------
// 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}; 

再次获取状态(整数)但不是路径名?????

【问题讨论】:

  • 欢迎来到 StackOverflow。这是询问 Delphi 问题的好地方,但最好 (a) 一次问一个问题,(b) 最好以其他人能够搜索并发现有用的方式提出问题。跨度>
  • 你用的是什么版本的Delphi?

标签: delphi dll


【解决方案1】:

函数想要获取一个字符缓冲区。这意味着你必须像这样分配它

Name1 : array[MAX_PATH+1] of AnsiChar;

MAX_PATH 在单元 Windows 中定义,应该足够大。 AnsiChar 适用于所有 Delphi 版本,相当于 C++ char

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

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

【讨论】:

    【解决方案2】:

    如果我不得不猜测,我会说您使用的是 Delphi 2009 或更高版本。作为 Unicode 转换的一部分,PChar 的含义在 D2009 中发生了变化。尝试改用 PAnsiChar,它应该可以工作。

    【讨论】:

      【解决方案3】:

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

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

      如果您使用的是 Delphi 2009 或更高版本,您必须将所有使用的 PChar 更改为 PAnsiChar,否则您会将错误大小的字符类型传递给需要单字节字符的 DLL .

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多