Reputation: 33
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
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
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
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