SafeArrays in CAuthor: Dave Date: 03.28.16 - 2:23am They say things come in 3's. So we might as well finish out with a safe array example of returning binary data from C to vb6. Technically you can use BSTRs for this, I played with it a bit the conversion on the C side was shady, this is better and works fine. (The testByteArray method would dump it to file and compare it to the md5 of the parent file. Everything checks out.) Private Declare Function binaryDataTest Lib "teds.dll" (buf() As Byte) As Long Private Declare Function retSa Lib "teds.dll" () As Byte() Private Sub Form_Load() Dim b() As Byte List1.AddItem "Testing safe array return type.." b() = retSa() testByteArray b() Erase b List1.AddItem "Testing safe array as argument.." retval = binaryDataTest(b) If retval > 0 Then testByteArray b() Else List1.AddItem "binaryDataTest failed with: " & retval End If End Sub int file_length(FILE *f) { int pos; int end; pos = ftell (f); fseek (f, 0, SEEK_END); end = ftell (f); fseek (f, pos, SEEK_SET); return end; } int __stdcall binaryDataTest(SAFEARRAY** psa) { #pragma EXPORT int retVal = 0; FILE* fp = fopen("teds.dll", "rb"); if(fp==0) return 0; int size = file_length(fp); unsigned char* dat = (unsigned char*)malloc(size); memset(dat, 0, size); fread(dat, 1, size, fp); fclose(fp); HRESULT hresult = SafeArrayAllocDescriptor(1,psa); if( FAILED(hresult)) goto cleanup; (*psa)->rgsabound[0].cElements = size; (*psa)->cbElements = 1; hresult = SafeArrayAllocData(*psa); if( FAILED(hresult) ) goto cleanup; for (long i = 0; i < size - 1; i++) { hresult = SafeArrayPutElement( *psa, &i, (void *)&dat[i] ); if(FAILED(hresult)) return 0; } retVal = 1; cleanup: free(dat); return retVal; } SAFEARRAY* __stdcall retSa() { #pragma EXPORT FILE* fp = fopen("teds.dll", "rb"); if(fp==0) return 0; int size = file_length(fp); unsigned char* dat = (unsigned char*)malloc(size); memset(dat, 0, size); fread(dat, 1, size, fp); fclose(fp); SAFEARRAYBOUND arrayBounds[1] = { {size, 0}}; SAFEARRAY* psa = SafeArrayCreate(VT_I1, 1, arrayBounds); SafeArrayLock(psa); unsigned char* pData = (unsigned char*)(psa->pvData); for (long i = 0; i < size - 1; i++) { pData[i] = dat[i]; } free(dat); SafeArrayUnlock(psa); return psa; } One thing I still have to research, what happens if you pass in a safearray that already has data in it? Might have a memleak there, or hit an array lock when trying to realloc its size. Comments: (0) |
About Me More Blogs Main Site |