LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to pass data from a Delphi pascal DLL class to a LabView data cluster?

Solved!
Go to solution

Hi all,

 

I have the following problem:

 

I'm using a dll written in Delphi Pascal to transfer data to LabView using the "Call Library Function Node".

 

My Delphi dll contains this class:

 

  TFlash=class
    Fi:TFileInfo;
    constructor Create;
    procedure LoadFi(Filedir_and_name:String);
  end;

 

 TFileInfo=record
    Idx:smallint; 
    IdxLstSpl:array[0..4] of longint;
    Ms:word;
    Sp:array[0..4]of word;
  end;

 

I've created the TFileInfo record datastructure into a LabView cluster to have the "same" variable.

My plan was to call a Deplhi DLL function with the "Call Library Function Node" and to pass the address of the TFileInfo record, so the data would be passed to the LabView Cluster.

 

When I make a simple delphi dll function like this, it works because I only pass an small integer to Labview (without reference to the data structure):

 

... 

var  Data:TFlash; 

... 

function GetNrOfRows(FilePath: string):integer;stdcall; 
begin
  Data:=TFlash.Create;
  Data.LoadFi(FilePath); //this function gets the number of rows out of the selected file.
  Result := Data.Fi.Idx;
end;

 

 

When I try to use this procedure instead of the function above, to pass the address of the whole complex data structure of "Data" (TFileInfo), I'm unable to get the information of "Data" into my Labview cluster:

 

procedure LoadFileInfo(FilePath: string; DataPointer: Pointer);stdcall; 
begin
  Data:=TFlash.Create;
  Data.LoadFi(FilePath);
  DataPointer:=@Data;
end;

 

Call Library Function Node settings:

- stdcall (WINAPI)

- Run in UI Thread

- Function prototype: void LoadFileInfo(PStr FilePath, void *DataPointer);

      * DataPointer --> Type: 'Adapt to Type' and Data format: 'Pointers to Handles'.

      * FilePath --> Type: 'string', string format: 'pascal string pointer'

 

I'm struggeling with this problem for almost a week now and I can't really find a solution on the forum or google.

I've also read the following posts:

 

http://forums.ni.com/ni/board/message?board.id=170&message.id=229930&requireLogin=False

http://forums.ni.com/ni/board/message?board.id=170&message.id=77947&requireLogin=False

http://forums.ni.com/ni/board/message?board.id=170&message.id=51245&requireLogin=False

 

(or did I miss something in these posts?)

 

Hope my explanation is clear.

Thx

0 Kudos
Message 1 of 4
(5,992 Views)

Correction: the pointer should return a pointer to the Fi Record, not pointer to the data class:

 

procedure LoadFileInfo(FilePath: string; DataPointer: Pointer);stdcall; 
begin
  Data:=TFlash.Create;
  Data.LoadFi(FilePath);
  DataPointer:=@Data.Fi;
end;

0 Kudos
Message 2 of 4
(5,978 Views)

Ok, I'm one step further:

 

Because it works when passing an integer from the dll to Labview,

I tried a simple vi containing a cluster with an small integer (16 bit signed Integer) in it and passing the pointer to that cluster:

 

same settings:

Call Library Function Node settings:

- stdcall (WINAPI)

- Run in UI Thread

- Function prototype: void LoadFileInfo(PStr FilePath, void *DataPointer);

      * DataPointer --> Type: 'Adapt to Type' and Data format: 'Pointers to Handles'. (and the cluster wired to the output of the Call Library Function Node)

      * FilePath --> Type: 'string', string format: 'pascal string pointer'

 

 

 

Changed the Delphi function to:

 

procedure LoadFileInfo(FilePath: string; DataPointer: Pinteger);stdcall; 
begin
  Data:=TFlash.Create;
  Data.LoadFi(FilePath);  --> this function fills in the data in Data.Fi
  DataPointer^:=Data.Fi.Idx; --> write the smallint on the address given by Labview
end;

 

 

When I call my DLL this way, the expected value appears in smallint indicator in de cluster on the front panel.

 

When I'm passing a pointer from the TFileInfo Type:

 

Delphi:

...

var  Data:TFlash;

type  PtrTFileInfo = ^TFileinfo;

...

procedure LoadFileInfo(FilePath: string; DataPointer: PtrTFileInfo);stdcall; 
begin
  Data:=TFlash.Create;
  Data.LoadFi(Copy(FilePath,2,length(FilePath)-1));
  DataPointer^:=Data.Fi;
end;

 

During debugging in my Delphi environment: when I get out of this function and pass this to Labview, an error occurs: access violation at 0x004E7125: read of address failed 0x00002A24. Process stopped.

 

Is it actually possible to access data with 2 applications? Delphi--> common stack <--Labview

0 Kudos
Message 3 of 4
(5,970 Views)
Solution
Accepted by topic author JrES

Again one step further:

 

Seems that isn't possible to pass data from Delphi to Labview through a DLL when I create in Labview a cluster with 2 arrays in it.

 

This Delphi part I had to realize in Labview:

 

TFileInfo=record
    Idx:smallint; {integer; Convert tool}
    IdxLstSpl:array[0..4] of longint;
    Ms:word;
    Sp:array[0..4]of word;
  end;

 

Instead of using 1 cluster with all the different data in it,I made a cluster (1) with my 2 elements (smallint and word).

To pass my data from my delphi arrays to labview I created another cluster (2) in cluster (1) with 5 longint elements (because my delphi array goes from 0..4), and another cluster (3) in cluster (1) with 5 word elements.

The rightclick on the cluster (1) and set the clusterorder in the correct order. First the smallint, then the longint array, then the word, and then the word-array.

 

When I then use this code in my Delphi dll, IT WORKS!:

 

procedure LoadFileInfo(FilePath: string; DataPointer: PtrTFileInfo);stdcall; 
begin
  Data:=TFlash.Create;
  Data.LoadFi(Copy(FilePath,2,length(FilePath)-1));         --> I have to cut off the first part of the pascal string because this is the length, and I only need the string itself
  DataPointer^:=Data.Fi;       --> pass the record structure to the Labview Cluster
end;

 

Thanks for the info Ralf!

0 Kudos
Message 4 of 4
(5,958 Views)