03-06-2023 03:12 AM - edited 03-06-2023 03:14 AM
Function called:
Rad_DGammaCode_Generate(DGamma_Input, &GammaCode_Output, AMORPHOUS);
typedef struct
{
double meas_x[Buf_Max];
double meas_y[Buf_Max];
double meas_LV[Buf_Max];
int meas_Gray[Buf_Max];
int meas_Count;
//input-set Target Parameter
int Target_Gray[Buf_Max];
int Target_Count;
double Target_x;
double Target_y;
double Target_Gamma_index;
int Target_RGB_Bits;
double dx_limit;
double dy_limit;
int Lv_weak;
bool Lv_weak_en;
//output
int R_LUT[Buf_Max];
int G_LUT[Buf_Max];
int B_LUT[Buf_Max];
int Gray[Buf_Max];
int Count;
double Lv_weak_per;
bool dx_limit_flag;
bool dy_limit_flag;
//Back test
double Back_x;
double Back_y;
int Gamma_Input_Bits;
bool E2PEN = false;
bool Bypass_Target_xy;
bool Low_Gray_enhance;
bool Gray_bypass;
}STRUCT_D3Gamma_General;
#pragma pack(push, 1)
typedef struct
{
unsigned char Address;
unsigned char Data;
}REGISTER;
#pragma pack(pop)
typedef struct
{
REGISTER *Reg_DGammaCode;
int DGammaCode_Length;
}D3GAMMA_OUTPUT;
have tried all the methods I can think of, please give me your help!!!!!!
03-06-2023 03:51 AM - edited 03-06-2023 03:57 AM
Test. Cannot post my reply here. Weird! I found out that placing text that reads like a C function call would make the server block my post.
03-06-2023 03:52 AM - edited 03-06-2023 03:56 AM
I also had to learn how to do it the hard way, with some help of the guys here in the forum.
The problem isn't the struct itself, it's the length in memory that it would have when you would call the DLL from a Windows executable.
In my case, due to data type alignment, the actual structure size was 5 bytes longer than counted, because Windows 32 bit executables would organize the memory in minimum block of 4 bytes (because it's 32 bits), but also in groups of 8. Your structure is either int [4 bytes], double [8 bytes], bool [4 bytes, yes, 4!] or char [1 byte].
So what is the goal? First, to find out how many bytes the structure occupies in memory. Can be done in an example project where you would insert a printf command to put out the size of the struct. Second, the decision whether you want to pass the struct as cluster, to be able to address single elements by name, or simply as array. The latter is much easier to pass once you found out the number of bytes, because you would just pass the DLL input an array of that size, but much harder to address elements, because for every element you would have to know the exact index.
Whatever you decide for - I went for the cluster way - it might require to insert fill bytes for the alignment.
03-06-2023 07:47 AM - edited 03-06-2023 08:06 AM
Just one correction here. bool is a C++ type. In true C way, its size is actually not guaranteed by the standard but it is usually 1 byte. But the C compiler in question is free to use any type it finds suitable to store a TRUE/FALSE value, including char, short, int, and long.
The C standard is notoriously ambiguous about the size of its datatypes, and only mandates that sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long). Only sizeof(char) specifically is defined to be always 1 but if that is in bytes, words or ints is again implementation specific (meaning every C compiler is free to choose and still adhere to the standard). In fact it doesn't even have to be a multiple of 8 bits, there used to be CPUs using 7 and 9 bits as register size and C was specifically designed to let the compiler builder choose the natural register size as base rather than trying to force a specific size.
They could theoretically all be one byte/octet, or septet or nonet and still conform to the C standard. Or they could all but the char be 4 bytes or even 8, or also 1 int.
bool was originally only present in C++ and was then added with C99 as a standard C type, albeit with some trickery. It is not a built in type in C since the C standard only reserves the original types char, short, int and long as integer types and states that anything else needs to be implemented as private built in types starting with an underscore and an uppercase letter. So C99 compliant compilers implement _Bool as built in type and then add a header stdbool.h that defines bool to be equivalent to _Bool. This is because there were already libraries that defined their own bool type and that would have clashed with a new built in bool type. Such libraries simply need to refrain from including <stdbool.h> and they will still compile as intended.
Your 4 byte boolean is most likely the Windows API BOOL32 type which is defined by the Windows headers as being equivalent to a DWORD. The actual bool type could be also 4 bytes and still conform to the C99 standard, since that standard does not mandate a specific size, but it is generally equivalent to 1 byte, some esoteric embedded compilers left outside of this discussion.
As to the original problem, it is likely related to the fixed size array elements in the cluster. Yes they look like arrays but are not equivalent to LabVIEW arrays in many ways. So you can not place LabVIEW arrays in a cluster and hope that they magically get converted to C arrays, either variable sized array pointers nor fixed sized embedded arrays.
The only way to build them in LabVIEW in a compatible way is to embedded them as another cluster of in your case Buf_Max elements. And yes that will give a monster cluster in your case if Buf_Max is anything but a very small number!
It may be actually easier to create a LabVIEW specific cluster with LabVIEW datatypes and then right click on the Call Library Node and select "Create C Code" and then fill in the according C file to translate between the LabVIEW way and the C way in that C code, compile it as a separate DLL and call that instead.
In any case the code and definitions you provide are not nearly enough to really know what needs to be done in detail. How those structure types relate to the function parameters is absolutely unclear as you choose to show the call of the function rather than its prototype. Even then the prototype is almost certainly not enough to understand how the data needs to be filled in and retrieved. This needs to be detailed in the according API documentation and/or retrieved from functional example code for how to call that function.