Definicja struktury Small i jednocześnie zdefiniowanie typu będącego wskaźnikiem na tę strukturę - SmallPrt:
Kod: Zaznacz cały
typedef struct Small {
double DoubleNr_1;
signed int IntNr;
double DoubleNr_2;
char CharValue[50];
double DoubleNr_3; } *SmallPtr;
Kod: Zaznacz cały
extern "C" __declspec(dllexport) int __stdcall OneSmall(int IntValue_1, SmallPtr SmallValue, int *IntValue_2){
SmallValue->IntNr=-123456789;
SmallValue->DoubleNr_1=123.456;
SmallValue->DoubleNr_2=234.567;
SmallValue->DoubleNr_3=345.678;
strncpy(SmallValue->CharValue, "00 abcDEF
10 abcDEF
20 abcDEF
30 abcDEF
40 abcDEF",50);
return IntValue_1+*IntValue_2; }
Wszystko wydaje sie proste, ale ugrzęzłem. Pierwszy problem to Ĺşle zwracana wartość DoubleNr_2 i DoubleNr_3 podczas gdy wartość DoubleNr_1 jest poprawna. Nie rozumiem też dlaczego zwracana wartość z funkcji typu int, która powinna byc sumą IntValue_1+IntValue_2, jest Ĺşle wyświetlona. Jak zrobiłem dll-kę która miała w strukturze int i char[n] to zwracana suma była poprawna. Nie było również problemów ze zwracaniem wartości int w strukturze.
Znalazłem definicje typów int, double. Wyglądają tak samo. W manualu do VC++ http://msdn2.microsoft.com/EN-US/librar ... S.80).aspx signed int, int is 4 bytes, range: –2,147,483,648 to 2,147,483,647 double is 8 bytes, range 1.7E +/- 308 (15 digits), stored as: sign bit, 11-bit exponent, 52-bit mantissa
W opisie dla LV data_manipulation.zip z Data Manipulation.ppt I32 is 32 bits=4 bytes DBL is 8 bytes, stored as: sign bit, 11-bit exp, 52-bit mantissa
VI z kodem: milib_onesmall.vi wygląda tak jak poniżej:
Wywołanie dll-ki
Wynik uruchomienia jest następujący:
Porównując z funkcją w dll-ce (powyżej) widać, że jest cos nie tak.
Drugim problemem na jaki się natknąłem to jak zrobić definicje char[n] gdy n>256 (256 ponieważ Array To Cluster ma ograniczenie do 256 znaków na wyjściu). Do tego jak to póĹşniej przekształcic na string w LV. Znalazłem, że można to zrobić stosujac np U64 zamiast U8, jednak problem pozostaje gdy tych U64 będzie wiecej niż 256 (np. dla char[5000]). Struktura z char[n], n>256:
Kod: Zaznacz cały
typedef struct Large {
double DoubleNr_1;
signed int IntNr;
double DoubleNr_2;
char CharValue[1000];
double DoubleNr_3; } *LargePtr;
Kod: Zaznacz cały
extern "C" __declspec(dllexport) int __stdcall OneLarge(int IntValue_1, LargePtr LargeValue, int *IntValue_2){
LargeValue->IntNr=-1123456789;
LargeValue->DoubleNr_1=9123.456;
LargeValue->DoubleNr_2=9234.567;
LargeValue->DoubleNr_3=9345.678;
strncpy(LargeValue->CharValue, "000 a-bcde-fghi-jklm-nopq-rstu-vwxy-zABC-DEFG-HIJK-LMNO-PQRS+TUVW-XYZa-bcde-fghi-jklm-nopq-rstu-vwx
100 a-bcde-fghi-jklm-nopq-rstu-vwxy-zABC-DEFG-HIJK-LMNO-PQRS+TUVW-XYZa-bcde-fghi-jklm-nopq-rstu-vwx
200 a-bcde-fghi-jklm-nopq-rstu-vwxy-zABC-DEFG-HIJK-LMNO-PQRS+TUVW-XYZa-bcde-fghi-jklm-nopq-rstu-vwx
300 a-bcde-fghi-jklm-nopq-rstu-vwxy-zABC-DEFG-HIJK-LMNO-PQRS+TUVW-XYZa-bcde-fghi-jklm-nopq-rstu-vwx
400 a-bcde-fghi-jklm-nopq-rstu-vwxy-zABC-DEFG-HIJK-LMNO-PQRS+TUVW-XYZa-bcde-fghi-jklm-nopq-rstu-vwx
500 a-bcde-fghi-jklm-nopq-rstu-vwxy-zABC-DEFG-HIJK-LMNO-PQRS+TUVW-XYZa-bcde-fghi-jklm-nopq-rstu-vwx
600 a-bcde-fghi-jklm-nopq-rstu-vwxy-zABC-DEFG-HIJK-LMNO-PQRS+TUVW-XYZa-bcde-fghi-jklm-nopq-rstu-vwx
700 a-bcde-fghi-jklm-nopq-rstu-vwxy-zABC-DEFG-HIJK-LMNO-PQRS+TUVW-XYZa-bcde-fghi-jklm-nopq-rstu-vwx
800 a-bcde-fghi-jklm-nopq-rstu-vwxy-zABC-DEFG-HIJK-LMNO-PQRS+TUVW-XYZa-bcde-fghi-jklm-nopq-rstu-vwx
900 a-bcde-fghi-jklm-nopq-rstu-vwxy-zABC-DEFG-HIJK-LMNO-PQRS+TUVW-XYZa-bcde-fghi-jklm-nopq-rstu-vwx",1000);
return IntValue_1+*IntValue_2; }
Funkcja wykorzystująca strukturę Small (potrójny wskaĹşnik do tej struktury):
Kod: Zaznacz cały
extern "C" __declspec(dllexport) int __stdcall FewSmall(int IntValue_1, SmallPtr **SmallValuePtr, int *IntValue_2, int *count){
int i;
SYSTEMTIME SysTime;
SmallPtr *SmallPtrTbl = NULL;
GetSystemTime(&SysTime);
*count=3+(int)SysTime.wMilliseconds/100; // 3...13
*SmallValuePtr=SmallPtrTbl=(SmallPtr *)calloc(*count + 1, sizeof(SmallPtr));
for(i = 0; i <*count; i++) {
SmallPtr SmallValueTbl = (SmallPtr)calloc(1, sizeof(Small));
SmallValueTbl->IntNr=1000+i;
SmallValueTbl->DoubleNr_1=123.456+1000*i;
SmallValueTbl->DoubleNr_2=234.567+10000*i;
SmallValueTbl->DoubleNr_3=345.678+100000*i;
sprintf(SmallValueTbl->CharValue, "00 abcDEF
10 abcDEF
20 abcDEF
30 abcDEF
40 abc %02d",i);
*SmallPtrTbl++=SmallValueTbl;
}
return IntValue_1+*IntValue_2; }
Wiem, że jednym z rozwiazań jest napisanie dll-ki pośredniczącej pomiedzy właściwą dll i LV. Chciałbym jednak tego uniknąć dlatego proszę Was o pomoc.
Zrobiłem przykłady użycia biblioteki w C++ milib_test.exe milib_test.cpp milib_test.zip - Projekt VC++ spakowany
Pozdrawiam, Maciek
PS Obrazki i pliki są z innego serwera, czasami trzeba przeładować stronę aby załadowały się obrazki.