Pass array parameter from external dll to Python - arrays

I tried to call a function from external DLL in Python.
The function prototype is:
void Myfunction(int32_t *ArraySize, uint64_t XmemData[])
This function creates a table of uint64 with "ArraySize" elements. This dll is generated by labview.
Here is the Python code to call this function:
import ctypes
# Load the library
dllhandle = ctypes.CDLL("SharedLib.dll")
#specify the parameter and return types
dllhandle.Myfunction.argtypes = [ctypes.c_int,ctypes.POINTER(ctypes.c_uint64)]
# Next, set the return types...
dllhandle.Myfunction.restype = None
#convert our Python data into C data
Array_Size = ctypes.c_int(10)
Array = (ctypes.c_uint64 * Array_Size.value)()
# Call function
dllhandle.Myfunction(Array_Size,Array)
for index, value in enumerate(Array):
print Array[index]
When executing this I got the error code:
dllhandle.ReadXmemBlock(Array_Size,Array)
WindowsError: exception: access violation reading 0x0000000A
I guess that I don't pass correctly the parameters to the function, but I can't figure it out.
I tried to sort simple data from the labview dll like a uint64, and that works fine; but as soon as I tried to pass arrays of uint64 I'm stuck.
Any help will be appreciated.

It looks like it's trying to access the memory address 0x0000000A (which is 10). This is because you're passing an int instead of a pointer to an int (although that's still an int), and you're making that int = 10.
I'd start with:
import ctypes
# Load the library
dllhandle = ctypes.CDLL("SharedLib.dll")
#specify the parameter and return types
dllhandle.Myfunction.argtypes = [POINTER(ctypes.c_int), # make this a pointer
ctypes.c_uint64 * 10]
# Next, set the return types...
dllhandle.Myfunction.restype = None
#convert our Python data into C data
Array_Size = ctypes.c_int(10)
Array = (ctypes.c_uint64 * Array_Size.value)()
# Call function
dllhandle.Myfunction(byref(Array_Size), Array) # pass pointer using byref
for index, value in enumerate(Array):
print Array[index]

Related

OCaml type constructors in C = <unknown constructor>

I've written some OCaml bindings for some C code; they seem to work fine, except that, at the interpreter, the type constructor appears to be opaque to OCaml. So, for example:
# #load "foo.cma" ;;
# open Foo ;;
# let b = barbie "bar";;
val b : Foo.kung = <unknown constructor>
# let k = ken "kenny" ;;
val k : Foo.tza = <abstr>
I'm trying to get rid of the <unknown constructor> and replace it with a meaningful print.
The contents of foo.ml are:
type kung = Tsau of string [##boxed] ;;
type tza ;; (* Obviously, an abstract type *)
external barbie : string -> kung = "barbie_doll" ;;
external ken : string -> tza = "ken_doll" ;;
The C code is the minimal amount of code to get this to work:
CAMLprim value barbie(value vstr) { ... }
CAMLprim value ken(value vsttr) { ... }
The actual C code uses caml_alloc_custom() to hold stuff; and obviously has to return what caml_alloc_custom() alloced, so that it doesn't get lost. That's the core reason for using custom types: so I can return the custom malloc's.
Even though these types are abstract or opaque, I'd like to have the let expression print something meaningful. For example, perhaps this?
val b : Foo.kung = "Hi my name is bar"
val k : Foo.tza = "Yo duude it's kenny"
The second question would be: if it's possible to print something meaningful, what should it be? Obviously, the constructors were invoked with strings, so whatever is printed should include those string values...
The third question is: is it possible to specify types and type constructors in C? I suspect that the answer is "obviously no", because OCaml types are static, compile-time types, and are not dynamically constructable. But it never hurts to ask. I mean, the ocaml interpreter is able to deal with brand new type declarations just fine, so somehow, OCaml types aren't entirely static; there's some kind of 'dynamic' aspect to them. I've not found any documentation on this.
As suggested in a comment, the answer is to use #install_printer, which is briefly touched on in the toplevel documentation. This is but a hint: example code as follows (keeping with the earlier example).
In foostubs.ml:
(** Signature declarations for C functions *)
external kung_prt : kung -> string = "c_kung_str" ;;
(* Need to #install_printer kung_pretty ;;
* FYI, the OCaml documentation is confusing
* as to what a Format.formatter actually is:
* it is used like a C stream or outport. *)
let kung_pretty : Format.formatter -> kung -> unit =
function oport ->
fun x -> Format.fprintf oport "Hi %s" (kung_prt x) ;;
The printer in C would look like this:
CAMLprim value c_kung_str(value vkung)
{
CAMLparam1(vkung);
const char* name = String_val(vkung);
char buff[200];
strcpy(buff, "my name is ");
strncat(buff, name, 200);
CAMLreturn(caml_copy_string(buff));
}
Then, either you have to tell the user to #install_printer kung_pretty ;; or, better yet, provide the user with a setupfoo.ml that does this, and tell them to #use "setupfoo.ml".

'withUnsafeBytes' is deprecated warning when passing void* argument to c function in swift 5

I have a library parsing FIT file in swift using an externally provided c library. The parsing function takes as argument a void * data.
To call the function, I was converting the data using data.withUnsafeBytes( { (ptr: UnsafePointer<UInt8>) in ...} to build the argument to the c function and it was working fine.
After the upgrade of Xcode to swift 5, I now get a deprecated warning
'withUnsafeBytes' is deprecated: use withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R instead
I couldn't work out how to fix the code to remove the deprecated warning. The code has been working fine and without warning in swift 4
I tried to change the argument in the closure to take UnsafeRawBufferPointer instead of the UnsafePointer but this resulted in an error in calling the function: Cannot convert 'UnsafeRawBufferPointer' to expected argument type 'UnsafeRawPointer?'
This is a small swift file to show the problem:
import Foundation
// Create sample data (Typically would be read from a file
let data = Data(repeating: 1, count: 10)
data.withUnsafeBytes( { (ptr : UnsafePointer<UInt8>) in
// call the c function with the void* argument
let value = readFITfile(ptr)
print( value )
})
And an example c function
unsigned readFITfile(const void * data){
//Silly example to show it works, just returning the value of pointer as int
//Typically would parse the data and return a structure
return (unsigned)data;
}
I saved a small repo with the above code here https://github.com/roznet/swift2c and the full scale project with the parsing of the file is here https://github.com/roznet/fit-sdk-swift
You have to change the closure argument to UnsafeRawBufferPointer and then take its baseAdress (which is a UnsafeRawPointer?, the Swift equivalent of void * in C):
data.withUnsafeBytes( { (ptr : UnsafeRawBufferPointer) in
let value = readFITfile(ptr.baseAddress)
// ...
})
The Swift compiler can also infer the closure argument type automatically:
data.withUnsafeBytes( { ptr in
let value = readFITfile(ptr.baseAddress)
// ...
})
For more information about this problem, see withUnsafeBytes Data API confusion in the Swift forum.
To get UnsafePointer now you should do something like that
data.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) in
if let ptrAddress = ptr.baseAddress, ptr.count > 0 {
let pointer = ptrAddress.assumingMemoryBound(to: UInt8.self) // here you got UnsafePointer<UInt8>
let value = readFITfile(ptr)
print( value )
} else {
// Here you should provide some error handling if you want ofc
}
}

Array type that is returned by a function in a module not defined

I have the following module:
module lexer
export parseCode
function parseCode(s::String)
lexeme::Array{UInt32, 1}
words = Dict("dup"=>UInt32(0x40000001), "drop"=>UInt32(0x40000002), "swap"=> UInt32(0x40000003), "+"=> UInt32(0x40000004), "-"=> UInt32(0x40000005), "x"=> UInt(0x4000000c),"/"=>UInt32(0x40000006), "%"=> UInt32(0x40000007), "if"=> UInt32(0x40000008),
"j"=> UInt32(0x40000009), "print"=> UInt32(0x4000000a), "exit"=>UInt32(b))
opcode = split(s)
for w in opcode
instruction::UInt32
instruction = get(words,w,0)
if instruction != 0
push!(lexeme,instruction)
end
end
push!(lexeme,UInt32(11))
return lexeme
end
end
The function parseCode parses words in the string s and fetches corresponding integer values for each word and pushes them into an array lexeme.
The function then returns the array to test.jl:
require("stackProcessor")
require("lexer")
using stackProcessor
using lexer
#=prog=Array{UInt32,4}
prog=[3,4,0x40000001, 5, 0x40000002, 3,0x40000003, 2, 0x40000004, 0x40000000]
processor(prog)
=#
f = open("opcode.txt")
s = readall(f)
close(f)
print(s)
opcode = parseCode(s)
print(repr(opcode))
processor(opcode)
Opcode is the variable that should be getting a copy of the lexeme array but I get the following error:
oadError: UndefVarError: lexeme not defined
in parseCode at C:\Users\Administrator\AppData\Local\atom\app-1.10.2\julia\lexer.jl:11
in include_string at loading.jl:282
in include_string at C:\Users\Administrator\.julia\v0.4\CodeTools\src\eval.jl:32
in anonymous at C:\Users\Administrator\.julia\v0.4\Atom\src\eval.jl:84
in withpath at C:\Users\Administrator\.julia\v0.4\Requires\src\require.jl:37
in withpath at C:\Users\Administrator\.julia\v0.4\Atom\src\eval.jl:53
[inlined code] from C:\Users\Administrator\.julia\v0.4\Atom\src\eval.jl:83
in anonymous at task.jl:58
while loading C:\Users\Administrator\AppData\Local\atom\app-1.10.2\julia\test.jl, in expression starting on line 17
Funny thing is it was working fine and now it's giving me this error.
I thought in Julia, arrays are returned as a copy so I can't figure where the error is coming from.
The line
lexeme::Array{UInt32, 1}
sounds like you were hoping to initialise a local variable ... but that isn't what that does. That's just a type assertion for an existing variable. I'm assuming that's line 11 that's producing the error, right?
The error is telling you that at the point were you tried to assert the type of the lexeme variable on line 11, that the particular variable hasn't yet been defined up to that point in the function.
Presumably it worked before you cleared your workspace because it was present as a global variable or something ...
If you want to initialise, do something like this instead:
lexeme = Array{UInt32,1}(0);

Array of structures in MATLAB Simulink

I am trying to create an array of structures in Simulink and got some problems with it.
first of all i tried to create it directly in Simulink using this:
function a = fcn(Dibhole, t , x, const)
%#codegen
%Output = zeros(10,10);
f1 = 'number';
f2 = 'move';
cube = struct(f1, 0, f2, 0);
a = repmat(cube, 20, 10);
for i = 1:20
for j = 1:10
a(i,j).number = 0;
a(i,j).move = 0;
end
end
and i got this error:
Derived output was of type struct. 'Inherited type' is unsupported for this
type and a defined bus object must be used instead. Click on 'a' and
set data type for 'a' to be 'Bus: ', where '' is
the name of a bus object from the MATLAB workspace.
So i found some example how to create struct in Matlab and receive this to Simulink: http://blogs.mathworks.com/seth/2011/12/05/initializing-buses-using-a-matlab-structure/
That works perfectly but i still can't repeat this with array:
f1 = 'number';
f2 = 'move';
cube = struct(f1, 0, f2, 0);
myStruct2 = repmat(cube, 20, 10);
for i = 1:20
for j = 1:10
myStruct2(i,j).number = 1;
myStruct2(i,j).move = 1;
end
end
busInfo = Simulink.Bus.createObject(myStruct2);
Can anyone clarify to me what's the problem? Or maybe there is different way to create array of struct in Simulink?
Mihail
Simulink wants you to define the output of the function to be a bus.
As 'Bus: My_test_bus', for example.
Take a look at the Simulink Bus Editor. You can find it in any model under the menu, Edit->Bus Editor.
This would be a good start.
Rick, i think you are right!
i have tried this problem for a long time, and have got this results:
the irony is that I was never able to create array of structures BUT i did this with structure of arrays! :D
I made this steps for it:
to use structure of arrays we need to define and initialize it in some MATLAB function. Like this:
number = zeros(10,1);
move = zeros(10,1);
for i = 1:10
number(i,1) = i+1;
move(i,1) = i+2;
end
a = struct('numbers',number,'movement', move);
To work this data we must use Bus Selector.
So we have array in "numbers" and "movement".
BUT! Here we go, Rick: we must define type of output of MATLAB function like Bus! How to do this in simulink? i found this way:
in model properties in simulink Callbacks/PreLoadFcn define some function and in same folder as project create .m file named like this just defined function.
In this file create structure of array and define Bus type for it:
number = zeros(10,1);
move = zeros(10,1);
a = struct('numbers',number,'movement', move);
busInfo = Simulink.Bus.createObject(a);
Now we have Bus type for our structure at first loading of simulink model.
Last step: define MATLAB function output type directly.
in Model Explorer choose your MATLAB function. choose output variable. Set DataType for it: Bus:slBus1 (the name of this Bus type you can see in wokspace of matlab, because its a global variable).
That's all! now it works!
(tried to add pictures, but i have no enough reputation :( )
Now my program works in this way, but i also tried to create array of structures and still have the problems. i tried to create Bus for it, but can't transmit it to Bus Selector - it doesn't know what to do with structures... i also tried to add one more MATLAB function to create some data from structures and then display it, but it doesn't works too(

LuaJit - Get metatable from module/package and assign it to userdata

Say I have this metatable for a custom struct vector2_t which is inside a module mymod like this:
local mymod = {}
local ffi = require("ffi")
local C = ffi.C
ffi.cdef[[
typedef struct
{
double x;
double y;
} vector2_t;
]]
local vector2_t
vector2_t = ffi.metatype("vector2_t", {
__eq = function(lhs, rhs)
if lhs.x == rhs.x and lhs.y == rhs.y
then return true else return false end
end
-- Member functions follow...
})
vcmp.vector2 = vector2_t
-- I use this method because the script is integrated in C/C++ as a string and not
-- as a file and I need a constant name that isn't decided by the file name
package.preload["mymod"] = function(mod) return mymod end
And in another script I have this callback/event listener function which must receive a vector2_t as it's argument:
local mymod = require "mymod"
local some_pos = mymod.vector2(32, 29.7)
-- That pos argument must be an instance of mymod.vector2_t
function position_update(pos)
print("New Pos: " .. pos.x .. ", " .. pos.y .. "\n")
some_pos.x = pos.x
some_pos.y = pos.y
end
Now, I must call that callback/event listener function from C/C++ and pass an instance of that vector2_t (along with it's associated metatable) as the parameter to that function.
typedef struct
{
double x;
double y;
} vector2_t;
void call_position_update(lua_State* L, double x, double y)
{
// Retrieve the function
lua_getglobal(L, "position_update");
// Validate it
if (!lua_isfunction(L, lua_gettop(L)))
{
lua_pop(L, 1);
return;
}
// Create an instance of vector2_t
vector2_t *pos = (vector2_t *)lua_newuserdata(L, sizeof(vector2_t));
// Assign the values to the new instance
pos->x = x;
pos->y = y;
// How do I get the meta table vector2_t on to the stack?
// Reach to the module somehow...
// Get the meta table from the module
luaL_getmetatable(L, "vector2_t");
// Assign the meta table to the vector2_t instance already on the stack
lua_setmetatable(L, -2);
// I'm assuming that the vector2_t instance is already on the stack so there's nothing else to push
// Call the function with 1 argument which should be that vector2_t onto the stack
if (!lua_pcall(L, 1, 0, 0))
{
printf("Error calling function 'position_update': %s\n", lua_tostring(_Lua, -1));
}
}
I'm a bit lost and I don't know how to pas an instance of that vector2_t as the function parameter. I'm sorry for posting so much code bu I wanted to be sure that I explained correctly.
cdata and userdata are completely different things. The only interaction they have is that you can get an FFI void* pointer to userdata. Notably, there is no C API for cdata objects. Mixing them is sure to cause you a lot of headaches.
Pick either the Lua C API or the FFI, and stick to it as much as possible.
To directly answer your question:
how to pas [sic] an instance of that vector2_t as the function parameter
To a Lua C API function, it gets passed on the stack, just like other values. Note that it will be a cdata typed object, not a userdata object. Notably, you can't get a pointer to it.
How do I get the meta table vector2_t on to the stack?
You can't, since you don't make the metatable accessible to outside scripts in your first script. luaL_getmetatable only works with metatables created with luaL_newmetatable

Resources