snm
snm

Reputation: 33

How can I use external DLL written in C from DELPHI

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 ?????

Upvotes: 3

Views: 2630

Answers (3)

Rob Kennedy
Rob Kennedy

Reputation: 163277

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.

Upvotes: 2

Matthias Alleweldt
Matthias Alleweldt

Reputation: 2453

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);

Upvotes: 5

Mason Wheeler
Mason Wheeler

Reputation: 84550

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.

Upvotes: 2

Related Questions