I am trying to use a DLL written in C, wrapping a Matlab DLL.
The function is defined in C as:
int wmlfLevel1(double* input2D, int size, char* message, double** output2d)
and my Delphi function is defined as:
func: function (input2d: pDouble; size: integer; messag: PAnsiChar; output2d: ppDouble): integer; cdecl;
I have defined these types to pass a matrix to the DLL:
type
TDynArrayOfDouble = array of double;
type
T2DDynArrayOfDouble = array of TDynArrayOfDouble;
type
ppDouble = ^pDouble;
and am calling the DLL function like this:
var
in2d: T2DDynArrayOfDouble;
size: integer;
msg: PAnsiChar;
out2d: T2DDynArrayOfDouble;
begin
size:= 3;
SetLength(in2d, size, size);
SetLength(out2d, size, size);
in2d[0][0]:= 1; ... // init matrix values
func(pDouble(in2d), size, msg, ppdouble(out2d));
The problem is the output matrix contains a huge amount of incorrect values (should contains the input matrix multiplied by 2).
What have I missed?
I can successfully call this DLL function using a static array with the following code:
type
T2DArrayOfDouble = array [0..2, 0..2] of double;
type
pT2DArrayOfDouble = ^T2DArrayOfDouble;
type
ppT2DArrayOfDouble = ^pT2DArrayOfDouble;
func: function (input2d: pT2DArrayOfDouble; size: integer; messag: PAnsiChar; output2d: ppT2DArrayOfDouble): integer; cdecl;
...
var
in2d: T2DArrayOfDouble;
size: integer;
msg: PAnsiChar;
out2d: pT2DArrayOfDouble;
begin
size:= High(in2d) + 1;
in2d[0][0]:= 1; ... // init matrix values
func(#in2d, size, msg, #out2d);
double* input2D
That's a pointer to an array of double. But you pass it
in2d: T2DArrayOfDouble
which is a pointer to an array of pointer to array of double.
In other words you are passing double** to a parameter that expects double*.
Solve the problem by changing
in2d: T2DArrayOfDouble
to
in2d: TDynArrayOfDouble
Obviously you'll have to change the SetLength to match, and the code that populated the array. Although one wonders if there isn't a deeper problem given that the argument name suggests that, contrary to the type, it is a two dimensional array.
Related
I am working with a C function in my Swift code that outputs an array. The function doesn't return an array because, apparently in C, functions are discouraged from returning arrays. Therefore, the function takes an in-out parameter (as a pointer) and places the array there.
The C function:
void kRing(H3Index origin, int k, H3Index* out);
H3Index* is the out parameter that takes the array. However, how do I get the array from this function in Swift? H3Index*, the out parameter, points to an integer. And, apparently in C, you can point to an integer, pass that pointer to a function, and that function can place an array in that pointer's place (even though it's pointing to an integer).
But because of Swift's type safety, this makes it difficult to get the array from the function. The Swift version:
kRing(origin: H3Index, k: Int32, out: UnsafeMutablePointer<H3Index>!)
My Swift implementation:
let h3Index: H3Index = 600022775385554943 // integer
let k: Int32 = 2 // integer
var result = H3Index() // the in-out parameter (must be integer to satisfy Swift's type safety)
_ = withUnsafeMutablePointer(to: &result) { kRing(h3Index, k, $0) }
print(result)
And it prints the result (with a bad access error, which I don't care about right now). But the result is an integer when it should be an array. How is this done?
The C implementation, for reference:
H3Index indexed = 0x8a2a1072b59ffffL; // 64-integer (hex)
int k = 2; // integer
int maxNeighboring = maxKringSize(k); // integer
H3Index* neighboring = calloc(maxNeighboring, sizeof(H3Index)); // the out parameter (a pointer to an integer and/or array)
kRing(indexed, k, neighboring); // the function
for (int i = 0; i < maxNeighboring; i++) {
if (neighboring[i] != 0) {
// iterate through array
}
}
In C,
H3Index* neighboring = calloc(maxNeighboring, sizeof(H3Index));
kRing(indexed, k, neighboring);
allocates memory for maxNeighboring elements of type H3Index and initializes the memory to zero. The address of that memory block (which is the address of the first element) is then passed to the kRing function.
It is possible to call calloc and free from Swift, but the easier to use API is Unsafe(Mutable)(Buffer)Pointer with its allocate() and deallocate() methods:
let neighboring = UnsafeMutableBufferPointer<H3Index>.allocate(capacity: maxNeighboring)
neighboring.initialize(repeating: 0)
kRing(indexed, k, neighboring.baseAddress)
Now you can print the values with
for i in 0..<maxNeighboring { print(neighboring[i]) }
or justs (because Unsafe(Mutable)BufferPointer is a collection that can be iterated over):
for neighbor in neighboring { print(neighbor) }
Eventually you must release the memory to avoid a memory leak:
neighboring.deallocate()
A simpler solution is to define a Swift array, and pass the address of the element storage to the C function:
var neighboring = Array<H3Index>(repeating: 0, count: maxNeighboring)
kRing(indexed, k, &neighboring)
for neighbor in neighboring { print(neighbor) }
neighboring is a local variable now, so that the memory is automatically released when the variable goes out of scope.
we are receiving (via UDP datagram) a float value codified by 4 bytes hex array.
We need to convert from 4 hex bytes to a float.
udp_data[0] = 'BE';
udp_data[1] = '7A';
udp_data[2] = 'E0';
udp_data[3] = 'F4';
In the given example, the correct equivalence, after transformation, udp_data is equivalent to -0.24499:
What is the optimal conversion in Twincat 3 PLC? maybe some library? We need to perform 52 transformation at once of this type.
I attached an example with an example taken from an online calculator:
Thanks!!
You can use a UNION type, which will at the same address hold a byte array (like the one you get from your UDP communication) and the real var which you want to convert to.
When you change the byte array, the real automatically reflects it. The conversion works the other way around also, in fact.
TYPE U_Convert :
UNION
arrUDP_Data: ARRAY [0 .. 3] OF BYTE; // Array must start with LSB
rReal : REAL;
END_UNION
END_TYPE
In MAIN you can declare the following var.
VAR
uConvert: U_Convert;
fValue : REAL;
END_VAR
And in the body of MAIN, update the byte array to requested values.
// Here we update the byte array
uConvert.arrUDP_Data[0] := 16#F4; // LSB
uConvert.arrUDP_Data[1] := 16#E0;
uConvert.arrUDP_Data[2] := 16#7A;
uConvert.arrUDP_Data[3] := 16#BE; // MSB
// Here we 'use' the converted value
fValue := uConvert.rReal;
I assume you have an array of bytes.
Header (put this in own function block if you want):
PROGRAM MAIN
VAR
aByteArray : ARRAY[1..4] OF BYTE := [16#F4, 16#E0, 16#7A, 16#BE];
pt : POINTER TO REAL;
fRealValue : REAL;
END_VAR
Body:
pt := ADR(aByteArray);
fRealValue := pt^;
Will give you the desired result:
s= struct('Hello',0,'World',0);
for i = 1: 5
s_vec(i) = s;
end
I have definied a struct in Matlab within a script. Now i want to implement a function witch change the Value of the Parameters.
For example:
function s_struct = set_s (number, prop , value)
s_struct(number).prop = value;
But the function returns a new struct. It does not change my input struct.
Where is my mistake?
I'am not sure to totally understand your question, but if you want to update a parameter in a structure, you have to pass the structure to update as argument of your function.
Moreover, if prop is the parameter, you should use an dynamic allocation using a string in your function :
function [ s_struct ] = set_s( s_struct, number, prop, value )
s_struct(number).(prop) = value;
end
Using it this way :
s_vec = set_s(s_vec, 2, 'Hello', 5);
It will update the second value to the parameter 'Hello' to 5.
Although I think Romain's answer is better practice, you can modify parameters without passing them in and out of a function if you use Nested Functions.
However, I do not like to use them because in complicated large functions it can be quite confusing trying to follow where things are being set and modified.
That being said here is an example of using a nested function to do what you want.
function nestedTest()
%Define your struct
s= struct('Hello',0,'World',0);
for i = 1: 5
s_vec(i) = s;
end
disp('Pre-Nested Call')
disp(s_vec(1))
set_s(1, 'Hello' , 1);%Set the first element of s_vec without passing it in.
disp('Post-Nested Call')
disp(s_vec(1))
function set_s (number, prop , value)
% Nested can modify vars defined in parent
s_vec(number).(prop) = value;
end
end
Output:
Pre-Nested Call
Hello: 0
World: 0
Post-Nested Call
Hello: 1
World: 0
If you want changing data outside your function (aka side effects) use classes instead of structures. Class must be a handle.
classdef MutableStruct < handle
properties
field1;
field2;
end
methods
function this = MutableStruct(val1, val2)
this.field1 = val1;
this.field2 = val2;
end
end
end
There is more information about correct initialization of object arrays:
MATLAB: Construct Object Arrays
The C-Code is stored in a DLL. I can load the DLL in MATLAB with the loadlibrary function. I am having trouble passing the wchar_t*[] parameter to the function. I do not know how to create this data type in MATLAB. Does anyone know how to create this type to pass to the calllib function?
MATLAB Code:
loadlibrary('test.dll', 'test.h');
str = '0';
ptr = libpoiner('voidPtrPtr', [int8(str) 0])
calllib('test.dll', 'testFunction', ptr) %this parameter does not match the wchar*[] type
outVal = ptr.Value
C-Code:
void testFunction(wchar_t* str[])
{
str[0] = L"test";
}
Output:
MATLAB allows the function to complete. The outVal variable is filled with garbage values.
If you are able to modify the C header files, you may try the following:
Adjust the header file to convert all wchar_t * to unsigned short *.
On the MATLAB side, the corresponding type would then be a uint16 array.
You could then typecast the uint16 array to char.
I figured it out. I changed the MATLAB code to the following:
loadlibrary('test.dll', 'test.h');
str = '0';
ptr = libpoiner('voidPtrPtr', [uint16(str) 0])
calllib('test.dll', 'testFunction', ptr) %this parameter does not match the wchar*[] type
outVal = ptr.Value
expectedOutput = char(outVal); %convert to ASCII
It outputs the values in decimal which confused me. When I converted them to ASCII, everything made sense.
I am trying to understand SystemVerilog function return values from the Language resource manual(Section 10.3.1), but I am having difficulties in grasping the following section. Can anyone help me interpret it? I tried looking in different sites but the information wasn't that deep.
In SystemVerilog, a function return can be a structure or union. In this case, a hierarchical name used inside the function and beginning with the function name is interpreted as a member of the return value. If the function name is used outside the function, the name indicates the scope of the whole function. If the function name is used within a hierarchical name, it also indicates the scope of the whole function.a = b + myfunc1(c, d); //call myfunc1 (defined above) as an expression
myprint(a); //call myprint (defined below) as a statement
function void myprint (int a);
...
endfunction
You can use two different ways to return a value from a function. For example as follows,
function int myfunc1(int c, d);
myfunc1 = c+d;
endfunction
and
function int myfunc1(int c, d);
return c+d;
endfunction
So when the function is declared as a structure or union type, the hierarchical name beginning with the function name also means the variable of the return value.
But the old LRM description is not right and precise now because the hierarchical name now could also be the function scope, not the return value. For example,
typedef struct { int c, d, n; } ST;
function ST myfunc1(int c, d);
static int x = 1;
myfunc1.c = c; // myfunc1 refers to the return structure
myfunc1.d = d; // myfunc1 refers to the return structure
myfunc1.n = c + d + // myfunc1 refers to the return structure
myfunc1.x; // myfunc1 refers to function scope
endfunction
Another interesting example of using hierarchical name containing the function name.
typedef struct { int c, d; } ST ;
module top;
function ST myfunc1(int c,d);
top.myfunc1.c = c;
myfunc1.c = 1;
myfunc1.d = d;
endfunction
ST x;
initial begin
x = myfunc1(3,2);
#1 $display("%d %d %d", x.c, x.d, top.myfunc1.c);
end
endmodule
The function call of x = myfunc1(3,2) constructs a call frame for myfunc1 and pass values for evaluation. The scopes of myfunc1 and top.myfunc1 are different. The hierarchical name beginning with myfunc1 refers to current call frame of the function, while top.myfunc1 refers to the scope of function declared inside the module top . So the message will be 1 2 3.
It looks like you are referencing a really old version of the LRM. Get the latest official version IEEE Std 1800-2012. You'll want to look at § 13.4.1 Return values and void functions. There is a line missing between quoted paragraph and quoted code:
Functions can be declared as type void, which do not have a return
value. Function calls may be used as expressions unless of type void,
which are statements:
The example code is not referring you your question hierarchical name access, it is an example of the void return type.
The example code below demonstrates hierarchical name access with a struct/union return types. Read about structs and unions in § 7.2 and § 7.3.
function struct { byte a,b; } struct_func (byte a,b);
byte c;
c = a ^ b;
struct_func.a = a; // <== hierarchical name used inside the function
struct_func.b = ~b;
endfunction
initial begin
// function name is used within a hierarchical name ( struct member )
$display("%h", struct_func(8'h42,8'hFE).b ); // returns 01
// function name is used within a hierarchical name ( function member )
$display("%h", struct_func.b ); // returns fe (last value of input b)
// function name is used within a hierarchical name ( function member )
$display("%h", struct_func.c ); // returns bc (last value of variable c)
end
Most cases you want to reuse struct/union definitions and should be defined as a typedef. The below function with the yeild the same results with the above initial block.
typedef struct { byte a,b; } my_struct;
function my_struct struct_func (byte a,b);
byte c;
c = a ^ b;
struct_func.a = a; // <== hierarchical name used inside the function
struct_func.b = ~b;
endfunction