How to call function from .dll library?
Moderator: Rathinagiri
Re: How to call function from .dll library?
Marek
Podaj typy parametrów przekazywanych do funkcji DataSend oraz typ zwracanej wartości.
Znajdziesz to w deklaracji funkcji.
Rozumiem, że jednym z parametrów jest struktura Scale.
Podaj typy parametrów przekazywanych do funkcji DataSend oraz typ zwracanej wartości.
Znajdziesz to w deklaracji funkcji.
Rozumiem, że jednym z parametrów jest struktura Scale.
Re: How to call function from .dll library?
Cześć Krzysztof, dzięki za zainteresowanie!
Podsyłam fragment dokumentacji.
Do wysyłania towarów na wagę poprzez parametry służy funkcja [ItemsSend[/b]
Możnaby napisać fragment w C, który będzie przekazywał właściwe parametry, spróbuję to jutro zrobić.
Niemniej cienki jestem po prostu z C
Podsyłam fragment dokumentacji.
Do wysyłania towarów na wagę poprzez parametry służy funkcja [ItemsSend[/b]
Możnaby napisać fragment w C, który będzie przekazywał właściwe parametry, spróbuję to jutro zrobić.
Niemniej cienki jestem po prostu z C
SEND ITEMS THROUGH PARAMETERS
It is not necessary to create a file, because all the articles and scales are inserted by code.
string WINAPI ItemsSend (Scale * myScales, int numScales,
Item * myItems, int numItems
int showWindow, int closeTime)
This function accepts as parameters all the articles to be sent and all data of the scales.
When the function is called, it sends all the articles to the scales. The function returns a
string which shows the result of the communication process when it completes the
process.
2.2.1 ItemsSend Function
This function allows sending a set of articles to the scales.
string WINAPI ItemsSend (Scale * myScales, int numScales,
Item * myItems, int numItems,
int showWindow, int closeTime)
Parameters:
1) myScales, Pointer to an array of “Scale” type structures with all the scales.
2) numScales, The total number of scales that the scales’ array has.
3) myItems, Pointer to an array of “Item” type structures with all the articles to be
sent to the scales.
4) numItems, The total number of articles that the articles’ array has.
5) showWindow, Show communication window.
Values: 0 -> Don’t show
1 -> Show
6) closeTime, Number of seconds that the window will be show alter
communication.
Values: -1 -> Close manually
X -> Number of seconds to close automatically
alter that the communication has finalized.
Result: The function will return a string with the following values:
1) If the communication with all the Scales is correct:
Result = “OK”
2) If the communication in any of the scales is not correct: It will return the
ipAddress of the scales with erroneous communication, separated with point &
comma (“;”)
Result = “192.168.1.2;192.168.1.3”
3) If the dll (commL.dll), which is necessary for the communication, has not been
added to the project, it will return a string “No commL.dll”.
Result = “No commL.dll”
Note: The register generated by ItemsSend function to send each Item is:
China -> L2_C
Rest -> AG ( 102E scale version or later is required )V 1.0.0.4_EN 7
SCALE STRUCTURE
This structure defines the scale with which the communication is stablished.
typedef struct _Scale
{
int masterAddress;
LPWSTR ipAddress;
int txPort;
int rxPort;
LPWSTR model;
LPWSTR display;
LPWSTR section;
int group;
LPWSTR logsPath;
}Scale;
Where:
- masterAddress: Logic address of the scale (Master Address). The registers will be
modified to assign this logic address.
Data type: int -> Integer without sign (4 bytes).
- ipAddress: IP address of the scale.
Data type: LPWSTR -> Wide character string.
- txPort: Port of the scale where we must connect for sending data to the scale.
Data type: int -> Integer without sign (4 bytes). (Is not in used)
- rxPort: Port of the scale where we must connect for receiving data to the scale.
Data type: int -> Integer without sign (4 bytes).
- model: Define the scale model.
Values:
500RANGE -> Is a Gamma 500 scale.
LSERIES -> Is a L series scale.
Data type: LPWSTR -> Wide character string.
- display: Type of scale display. (Is not in used)
Values:
ALPHANUMERIC -> Scale with alphanumeric display
GRAPHIC -> Scale with graphic display
Data type: LPWSTR -> Wide character string.
- section: Sections associated to the scale. If there are multiple sections they must be
separated with commas (“,”).(Is not in used)
Data type: LPWSTR -> Wide character string.
- group: Group of the scale. The registers will be modified to assign this Group number.
Data type: int -> Integer without sign (4 bytes).
- logsPath: Path for the logs file, this file have all the registers of communication. If it is
empty the communication logs will not be recorded. (It is not used)
Data type: LPWSTR -> Wide character string.V 1.0.0.4_EN 8
ITEM STRUCTURE
This is the structure to define the article data to be sent to the scale.
typedef struct _Item
{
int code;
int directKey;
double price;
LPWSTR name;
int type;
int section;
LPWSTR expiryDate;
int alterPrice;
int number;
int priceFactor;
LPWSTR textG;
}Item;
Where:
- code : Article Identification code (maxValue = 999999).
Data type: int -> Integer without sign (4 bytes).
- directKey: Direct key associated to the article (maxValue = 999).
Data type: int -> Integer without sign (4 bytes).
- price: Article price (maxValue= 9999,99). Data type: double(8 bytes)
- name: Article name (maxLength=36 bytes, for China).
Data type: LPWSTR -> Wide character string.
- type: Type of article. Data type: int -> Integer without sign (4 bytes).
0-> Weighed
1-> Non Weighed
- section: Article section. Data type: int -> Integer without sign (4 bytes).
- expiryDate: Best before date (format: dd/MM/yyyy).
Data type:LPCSTR -> Character string constant.
- alterPrice: Allows to modify the item price. Data type: int->Integer without sign (4
bytes). 0 -> Allows to modify the price.
1 -> Don’t allow to modify the price.
- number: PLUNumber, 9 digits number to be printed in the label
(maxValue=999999999)
Data type: int -> Integer without sign (4 bytes).
- priceFactor: Determines the weight base of the price.
Data type: int -> Integer without sign (4 bytes).
0 -> Yuan/kg
1 -> Yuan/100g
2 -> Yuan/500g
- textG: Item G text. (maxLegth = 1024 bytes). Data type: Byte array. (It is not used
[/
Re: How to call function from .dll library?
My idea is to write function in C which calls ItemsSend funtion from .dll
But, I need to transfer to C function two 2-dimensional arrays.
I don't know how to manipulate nested array passed to function in C api.
I can get master array by aScales= hb_param(1, HB_IT_ARRAY), is it correct?
but:
aScale = aScales[0];
is it correct?
Has anybody sample of C code?
But, I need to transfer to C function two 2-dimensional arrays.
I don't know how to manipulate nested array passed to function in C api.
I can get master array by aScales= hb_param(1, HB_IT_ARRAY), is it correct?
but:
aScale = aScales[0];
is it correct?
Has anybody sample of C code?
Last edited by mol on Sat Jun 17, 2017 2:15 pm, edited 1 time in total.
Re: How to call function from .dll library?
Strings have variable length, so, how should they be terminated? by chr(0) (as I remember chr(0) is string terminator in C)apais wrote: ↑Fri Jun 16, 2017 4:46 pm A C structure is a continuous and positional list of characters, while a harbour array is a pointer to a dynamic non-continuous set of chars.
In your case the representation of the structure would be something similar to: 00192.168.20.18130013000500RANGEALPHANUMERICSection0
But I'm sure a C profesional can tell you the exact translation of that. You have to know how many digits an int is and the exact length of the structure.
Also how they represent a null char for the last parameter
HTH
Angel
Re: How to call function from .dll library?
Marek
Try this. Compiled without errors, but I have no possibility to test.
Try this. Compiled without errors, but I have no possibility to test.
Code: Select all
#include "hmg.ch"
FUNCTION Main()
LOCAL aScale := {}
LOCAL aItem := {}
LOCAL lShowWindow := .T.
LOCAL nCloseTime := -1
aAdd(aScale, { 0, ; //masterAddress
"192.168.1.2", ; //ipAddress
3001, ; //txPort
3000, ; //rxPort
"500RANGE", ; //model
"ALPHANUMERIC", ; //display
"Section", ; //section
0, ; //group
"" ; //logsPath
})
aAdd(aScale, { 0, ; //masterAddress
"192.168.1.3", ; //ipAddress
3001, ; //txPort
3000, ; //rxPort
"500RANGE", ; //model
"ALPHANUMERIC", ; //display
"Section", ; //section
0, ; //group
"" ; //logsPath
})
aAdd(aItem, { 1, ; //code
1, ; //directKey
24.51, ; //price
"Name1", ; //name
0, ; //type
9, ; //section
"18/07/2017", ; //expiryDate
0, ; //alterPrice
999999999, ; //number
0, ; //priceFactor
"" ; //textG
})
aAdd(aItem, { 2, ; //code
1, ; //directKey
19.37, ; //price
"Name2", ; //name
0, ; //type
9, ; //section
"18/10/2017", ; //expiryDate
0, ; //alterPrice
999999998, ; //number
0, ; //priceFactor
"" ; //textG
})
MsgBox(Dibalscop_ItemsSend(aScale, aItem, lShowWindow, nCloseTime))
RETURN NIL
#pragma BEGINDUMP
#include "SET_COMPILE_HMG_UNICODE.ch"
#include "HMG_UNICODE.h"
#include <windows.h>
#include "hbapi.h"
#include "hbapiitm.h"
typedef struct _SCALE
{
INT masterAddress;
LPWSTR ipAddress;
INT txPort;
INT rxPort;
LPWSTR model;
LPWSTR display;
LPWSTR section;
INT group;
LPWSTR logsPath;
} SCALE;
typedef struct _ITEM
{
INT code;
INT directKey;
DOUBLE price;
LPWSTR name;
INT type;
INT section;
LPWSTR expiryDate;
INT alterPrice;
INT number;
INT priceFactor;
LPWSTR textG;
} ITEM;
//Dibalscop_ItemsSend(aScale, aItem, lShowWindow, nCloseTime)
HB_FUNC ( DIBALSCOP_ITEMSSEND )
{
LPWSTR WINAPI (*pItemsSend)(SCALE * myScales, INT numScales, ITEM * myItems, INT numItems, INT showWindow, INT closeTime);
HMODULE hLib = LoadLibraryA("Dibalscop.dll");
PHB_ITEM pArray = hb_itemNew(NULL);
PHB_ITEM pSubArray = hb_itemNew(NULL);
HB_SIZE nScales;
HB_SIZE nItems;
UINT n;
if (hLib)
{
pItemsSend = (LPWSTR WINAPI (*)(SCALE *, INT, ITEM *, INT, INT, INT)) GetProcAddress(hLib, "ItemsSend");
if (pItemsSend)
{
pArray = hb_param(1, HB_IT_ARRAY);
nScales = hb_arrayLen(pArray);
SCALE sc[nScales];
for (n = 0; n < nScales; ++n)
{
hb_arrayGet(pArray, n+1, pSubArray);
sc[n].masterAddress = (INT) hb_arrayGetNI (pSubArray, 1);
sc[n].ipAddress = (LPWSTR) HMG_arrayGetCPtr(pSubArray, 2);
sc[n].txPort = (INT) hb_arrayGetNI (pSubArray, 3);
sc[n].rxPort = (INT) hb_arrayGetNI (pSubArray, 4);
sc[n].model = (LPWSTR) HMG_arrayGetCPtr(pSubArray, 5);
sc[n].display = (LPWSTR) HMG_arrayGetCPtr(pSubArray, 6);
sc[n].section = (LPWSTR) HMG_arrayGetCPtr(pSubArray, 7);
sc[n].group = (INT) hb_arrayGetNI (pSubArray, 8);
sc[n].logsPath = (LPWSTR) HMG_arrayGetCPtr(pSubArray, 9);
}
pArray = hb_param(2, HB_IT_ARRAY);
nItems = hb_arrayLen(pArray);
ITEM it[nItems];
for (n = 0; n < nItems; ++n)
{
hb_arrayGet(pArray, n+1, pSubArray);
it[n].code = (INT) hb_arrayGetNI (pSubArray, 1);
it[n].directKey = (INT) HMG_arrayGetCPtr(pSubArray, 2);
it[n].price = (DOUBLE) hb_arrayGetND (pSubArray, 3);
it[n].name = (LPWSTR) hb_arrayGetNI (pSubArray, 4);
it[n].type = (INT) HMG_arrayGetCPtr(pSubArray, 5);
it[n].section = (INT) HMG_arrayGetCPtr(pSubArray, 6);
it[n].expiryDate = (LPWSTR) HMG_arrayGetCPtr(pSubArray, 7);
it[n].alterPrice = (INT) hb_arrayGetNI (pSubArray, 8);
it[n].number = (INT) HMG_arrayGetCPtr(pSubArray, 9);
it[n].priceFactor = (INT) HMG_arrayGetCPtr(pSubArray, 10);
it[n].textG = (LPWSTR) HMG_arrayGetCPtr(pSubArray, 11);
}
HMG_retc(pItemsSend(sc, nScales, it, nItems, hb_parl(3), hb_parni(4)));
}
else
{
HMG_retc(L"No ItemsSend function");
}
FreeLibrary(hLib);
}
else
{
HMG_retc(L"No Dibalscop.dll");
}
}
#pragma ENDDUMP
/*
SEND ITEMS THROUGH PARAMETERS
It is not necessary to create a file, because all the articles and scales are inserted by code.
string WINAPI ItemsSend (Scale * myScales, int numScales,
Item * myItems, int numItems
int showWindow, int closeTime)
This function accepts as parameters all the articles to be sent and all data of the scales.
When the function is called, it sends all the articles to the scales. The function returns a
string which shows the result of the communication process when it completes the
process.
2.2.1 ItemsSend Function
This function allows sending a set of articles to the scales.
string WINAPI ItemsSend (Scale * myScales, int numScales,
Item * myItems, int numItems,
int showWindow, int closeTime)
Parameters:
1) myScales, Pointer to an array of “Scale” type structures with all the scales.
2) numScales, The total number of scales that the scales’ array has.
3) myItems, Pointer to an array of “Item” type structures with all the articles to be
sent to the scales.
4) numItems, The total number of articles that the articles’ array has.
5) showWindow, Show communication window.
Values: 0 -> Don’t show
1 -> Show
6) closeTime, Number of seconds that the window will be show alter
communication.
Values: -1 -> Close manually
X -> Number of seconds to close automatically
alter that the communication has finalized.
Result: The function will return a string with the following values:
1) If the communication with all the Scales is correct:
Result = “OK”
2) If the communication in any of the scales is not correct: It will return the
ipAddress of the scales with erroneous communication, separated with point &
comma (“;”)
Result = “192.168.1.2;192.168.1.3”
3) If the dll (commL.dll), which is necessary for the communication, has not been
added to the project, it will return a string “No commL.dll”.
Result = “No commL.dll”
Note: The register generated by ItemsSend function to send each Item is:
China -> L2_C
Rest -> AG ( 102E scale version or later is required )V 1.0.0.4_EN 7
SCALE STRUCTURE
This structure defines the scale with which the communication is stablished.
typedef struct _Scale
{
int masterAddress;
LPWSTR ipAddress;
int txPort;
int rxPort;
LPWSTR model;
LPWSTR display;
LPWSTR section;
int group;
LPWSTR logsPath;
}Scale;
Where:
- masterAddress: Logic address of the scale (Master Address). The registers will be
modified to assign this logic address.
Data type: int -> Integer without sign (4 bytes).
- ipAddress: IP address of the scale.
Data type: LPWSTR -> Wide character string.
- txPort: Port of the scale where we must connect for sending data to the scale.
Data type: int -> Integer without sign (4 bytes). (Is not in used)
- rxPort: Port of the scale where we must connect for receiving data to the scale.
Data type: int -> Integer without sign (4 bytes).
- model: Define the scale model.
Values:
500RANGE -> Is a Gamma 500 scale.
LSERIES -> Is a L series scale.
Data type: LPWSTR -> Wide character string.
- display: Type of scale display. (Is not in used)
Values:
ALPHANUMERIC -> Scale with alphanumeric display
GRAPHIC -> Scale with graphic display
Data type: LPWSTR -> Wide character string.
- section: Sections associated to the scale. If there are multiple sections they must be
separated with commas (“,”).(Is not in used)
Data type: LPWSTR -> Wide character string.
- group: Group of the scale. The registers will be modified to assign this Group number.
Data type: int -> Integer without sign (4 bytes).
- logsPath: Path for the logs file, this file have all the registers of communication. If it is
empty the communication logs will not be recorded. (It is not used)
Data type: LPWSTR -> Wide character string.V 1.0.0.4_EN 8
ITEM STRUCTURE
This is the structure to define the article data to be sent to the scale.
typedef struct _Item
{
int code;
int directKey;
double price;
LPWSTR name;
int type;
int section;
LPWSTR expiryDate;
int alterPrice;
int number;
int priceFactor;
LPWSTR textG;
}Item;
Where:
- code : Article Identification code (maxValue = 999999).
Data type: int -> Integer without sign (4 bytes).
- directKey: Direct key associated to the article (maxValue = 999).
Data type: int -> Integer without sign (4 bytes).
- price: Article price (maxValue= 9999,99). Data type: double(8 bytes)
- name: Article name (maxLength=36 bytes, for China).
Data type: LPWSTR -> Wide character string.
- type: Type of article. Data type: int -> Integer without sign (4 bytes).
0-> Weighed
1-> Non Weighed
- section: Article section. Data type: int -> Integer without sign (4 bytes).
- expiryDate: Best before date (format: dd/MM/yyyy).
Data type:LPCSTR -> Character string constant.
- alterPrice: Allows to modify the item price. Data type: int->Integer without sign (4
bytes). 0 -> Allows to modify the price.
1 -> Don’t allow to modify the price.
- number: PLUNumber, 9 digits number to be printed in the label
(maxValue=999999999)
Data type: int -> Integer without sign (4 bytes).
- priceFactor: Determines the weight base of the price.
Data type: int -> Integer without sign (4 bytes).
0 -> Yuan/kg
1 -> Yuan/100g
2 -> Yuan/500g
- textG: Item G text. (maxLegth = 1024 bytes). Data type: Byte array. (It is not used
*/
Re: How to call function from .dll library?
Wow! I'll test as soon as possible. Now is 11 pm, my wife is sitting by me
Re: How to call function from .dll library?
Hi Krzysztof!
You've made some mistakes in the loop reading Items - with data types
I've changed and now all works OK
Thank you again!
You've made some mistakes in the loop reading Items - with data types
I've changed and now all works OK
Code: Select all
for (n = 0; n < nItems; ++n)
{
hb_arrayGet(pArray, n+1, pSubArray);
it[n].code = (INT) hb_arrayGetNI (pSubArray, 1);
it[n].directKey = (INT) hb_arrayGetNI (pSubArray, 2);
it[n].price = (DOUBLE) hb_arrayGetND (pSubArray, 3);
it[n].name = (LPWSTR) HMG_arrayGetCPtr(pSubArray, 4);
it[n].type = (INT) hb_arrayGetNI (pSubArray, 5);
it[n].section = (INT) hb_arrayGetNI (pSubArray, 6);
it[n].expiryDate = (LPWSTR) HMG_arrayGetCPtr(pSubArray, 7);
it[n].alterPrice = (INT) hb_arrayGetNI (pSubArray, 8);
it[n].number = (INT) hb_arrayGetNI (pSubArray, 9);
it[n].priceFactor = (INT) hb_arrayGetNI (pSubArray, 10);
it[n].textG = (LPWSTR) HMG_arrayGetCPtr(pSubArray, 11);
}
Re: How to call function from .dll library?
I am pleasantly surprised that I didn't make other mistakes.
Re: How to call function from .dll library?
Bravo !
Now I've learned how to traslate a Harbour array to a C structure.
Thank you
Now I've learned how to traslate a Harbour array to a C structure.
Thank you
Angel Pais
Web Apps consultant/architect/developer.
Web Apps consultant/architect/developer.