Work with DLL file
显示 更早的评论
Hello,
im trying to work with a DMD from Vialux. All i know is that i have to use the functions from the DLL File. I loaded it and all functions are in the workspace.
Now i want to use at frist one function "AlpDev Alloc". In the Description it says "long AlpDevAlloc (long DeviceNum, long InitFlag, ALP_ID *DeviceIdPtr)". I get three ouputs but i have to give three inputs. First two of them are given as "ALP_DEFAULT" for DeviceNum and InitFlag (4 byte integer value). For "DeviveIdPtr" pointer to a writeable 4-byte integer. Its completly new for me with DLLs, could anyone help with this question what i have to do with "ALP_ID *DevideIdPtr" and is the rest correct?
Thanks a lot!
loadlibrary('alp4395', 'alp.h');
libfunc = libfunctions('alp4395');
% long AlpDevAlloc (long DeviceNum, long InitFlag, ALP_ID *DeviceIdPtr) in documentation
[res1, res2, res3] = calllib('alp4395',libfunc{1,1},'ALP_Default', 'ALP_Default',?);
5 个评论
Mohammad Sami
2020-1-25
you will need to create a pointer before you can call the function
ptr = libpointer(DataType); % e.g. DataType = 'int32'
DeviceNum = 1;
InitFlag = 1;
[res1, res2, res3] = calllib('alp4395','AlpDevAlloc',DeviceNum,InitFlag,ptr);
Peer Blumido
2020-1-27
Mohammad Sami
2020-1-28
编辑:Mohammad Sami
2020-1-28
Is ALP_DEFAULT a constant defined in the dll ? I think you will need to pass in the actual numeric value of the constant as the signature asks for long. ulongPtr would be uint32 pointer.
Also do note the pointer is initialised to a null value.
Peer Blumido
2020-1-28
编辑:Peer Blumido
2020-1-28
Guillaume
2020-1-28
Can you check in the dll documentation what a return value of 1001 mean?
回答(2 个)
Guillaume
2020-1-28
Your dll function takes 3 inputs, the first two are scalar numeric indeed. The snippet of documentation you show is not very clear but indeed it looks like you want 0 for the default.
The 3rd input is a pointer to some memory where the function will write something.From your header file snippet it looks like it is indeed a 4-bit unsigned integer (assuming that the dll defines long as a 32-bit integer, which is fairly standard but not guaranteed).
The function only has one output, which is probably an error code or success. I'm unclear why you say you get 3 outputs.
In theory,
deviceptr = libpointer('uint32'); %No need to assign a value, it's overwritten by AlpDevAlloc
res = calllib('alp4395', 'AlpDevAlloc', 0, 0, deviceptr);
ALP_ID = deviceptr.Value;
should work according to the information you've provided. However, do check the value of res against the dll documentation as it may indicate an error of some kind.
If you get a matlab error with the above, then we've not properly understood the signature.
Note that when you did:
ALP_ID = libpointer;
res1 = calllib('alp4395','AlpDevAlloc',DeviceNum,InitFlag,ALP_ID);
you passed a NULL pointer to the library. Two things can happen in this case: the library tries to write to the NULL address and crashes, or the dll checks that the pointer is not NULL and returns an error. Since it didn't crash, it must have returned an error code which I assumes is that 1001 value.
Peer Blumido
2020-1-28
编辑:Peer Blumido
2020-1-28
8 个评论
Guillaume
2020-1-28
"matlab crashed": do you really mean crash (you have to restart matlab) or error? If matlab did crash, that's a problem with the dll itself, not much you can do about that. Possibly, the dll doesn't behave well if it still holds resources when it is unloaded. Only the dll authors can fix this.
So, yes if you get 1001 that means that the function call worked but you either passed some invalid values or the device can't be connected to. It looks like it worked on your second try and you connected to a device with ID 353.
Most likely, if you're connected and you attempt another connection, you'll get error 1001.
Make sure that you call AlpDevFree if you succesfully connected. That may help in preventing crashes.
Mohammad Sami
2020-1-29
Yes, you would need to deallocate any resources, before unloading the dll. I have experienced such crashes before.
Based on what worked. device id is pointer to uint32 = unsigned long, while the DeviceNum and InitFlag are int32 = long.
So the error in my earlier comment was not to explicitly initialise DeviceNum and InitFlag as int32 class. I had thought matlab will translate this automatically, based on the function signature.
If you need to use this interface often, I would recommend that you make your own Matlab Wrapper class around your dll. That way you can track if the library is loaded and all the resources that you have kept open. You will need to write a custom delete function to free up the open resources and unload the library.
Guillaume
2020-1-29
Like Mohammad, I'm a bit surprised that you have to explicitly tell cast the values to their respective C type. Matlab is supposed to do that for you.
Mohammad suggestion of wrapping the dll into a class is a very good one. It would go something like this:
classdef ALPWrapper < handle
properties %store here all resources that must be released before unloading
allocatedALP; %array to store all allocated devices. They must be deallocated prior to unloading
end
properties (Constant, Access = Private)
libname = 'alp4395'
end
methods
function this = ALPWrapper %constructor
%load the library
loadlibrary('alp4395.dll', 'alp.h');
%other initialisation tasks
end
function delete(this) %destructor
for dev = 1:numel(allocatedALP)
this.FreeDevice(allocatedALP(dev));
end
%after freeing all resources unload the library
unloadlibrary('alp4395');
end
function AllocateDevice(this, DeviceNumber, InitFlag)
deviceid = 0; %gets overwritten by AlpDevAlloc
devptr = libpointer('uint32Ptr', 0);
errcode = calllib(this.libname, 'AlpDevAlloc', DeviceNumber, InitFlag, devptr);
if errcode ~= 0
error('Failed to allocated device, error code is: %d', errcode);
end
this.allocatedALP = [this.allocatedALP, devptr.Value];
end
function FreeDevice(this, DeviceId)
[found, where] = ismember(DeviceId, this.allocatedALP);
assert(found, 'Device has not been allocated');
errcode = calllib(this.libname, 'AlpDevFree', DeviceId); %I'm making assumption about the signature of this function
if errcode ~= 0
warning('Deallocation may not have been successful, error code is: %d', errcode);
end
this.allocatedALP(where) = [];
end
end
end
To unload the library, you just have to clear the class object, e.g.:
alplib = ALPWrapper; %this loads the library and perform any required initialisation
alpid = alplib.AllocateDevice(0, 0); %use defaults
%...do something
clear('alplib'); %automatically deallocate device and unload the library
Peer Blumido
2020-1-29
编辑:Peer Blumido
2020-1-29
Guillaume
2020-1-29
Regarding return value, it sounds like it's always going to be an error code, so you'll be calling all the functions with:
errcode = calllib(['alp4395', 'funname', arg1, arg2, ..);
and if you don't get 0 as errcode, something is not right. You posted the meaning of the error codes earlier. E.g if errcode is 1005, this is ALP_PARM_INVALID meaning you passed an invalid value to the function.
No idea why the device ID is changing. It's totally up to the authors of the dll how this work. You need to ask them.
With regards to AlpDevControl, well you need to decide what operation you want to perform (1st argument) and the corresponding value you want to set. E.g if you want to set the DMD type to 1080 .65'' type A, the control type is 2021 (ALP_DEV_DMDTYPE) and the control value is 10 (ALP_DMDTYPE_1080P_065A), so:
errcode = calllib('ap4395', 'AlpDevControl', ALP_ID, 1080, 10);
To disable timeout:
errcode = calllib('ap4395', 'AlpDevControl', ALP_ID, 2014, 1); %ALP_TRIGGER_TIME_OUT, ALP_TIME_OUT_DISABLE
etc.
Peer Blumido
2020-1-30
Mohammad Sami
2020-1-30
Looks like you have manage to get it to work. You can add these as functions in your wrapper class.
Mohammad Sami
2020-1-30
Also I would recommend that your class manage all the pointers internally. If any of the c functions return pointers those may need to be freed once you don't need them or when you are deleting this object.
What I did was to create a private property to store pointers in a cell array. Once the pointer is cleared in C (your dll my have a clear or free function), just set it to libpointer (null).
If a function in c returns a pointer, its stored in the cell array, and i return the cell array index rather then the pointer.
% release pointers
if(~obj.pointers{i}.isNull)
calllib('lib...','release....free...',obj.pointers{i});
obj.pointers{i} = libpointer; % set to null
end
类别
在 帮助中心 和 File Exchange 中查找有关 Performance and Memory 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!










