You're right, the brackets were missing... it's been so long since I was fluent in C...Quote:
Originally Posted by Joacim Andersson
Printable View
You're right, the brackets were missing... it's been so long since I was fluent in C...Quote:
Originally Posted by Joacim Andersson
Actually it was the other way round:Quote:
Originally Posted by moeur
BufferSize = dsize\3 and not 2*dsize\3
I don't get any errors now, but the Val12bit values calculated in the dll are wrong because some of them come out negative. Maybe the variable type is not correct and it should be "unsigned" or something...?
But we're getting close.
I don't remember the order, but isn't a bit wise operation evaluated before a multiplication in C? If so then this code is wrong:To me it looks like you, on the first line, multiply with 16 | DataByte[i][0] which is not what you want to do. Try this:Code:Val12bit[j] = (DataByte[i][2] & 240) * 16 | DataByte[i][0];
Val12bit[j + 1] = (DataByte[i][2] & 15) * 256 | DataByte[i][1];
Code:Val12bit[j] = ((DataByte[i][2] & 240) * 16) | DataByte[i][0];
Val12bit[j + 1] = ((DataByte[i][2] & 15) * 256) | DataByte[i][1];
This can be further optimized by removing the painfully slow multiplication operation and replacing it with a bit shift:Quote:
Originally Posted by Joacim Andersson
Always replace multiplications and divisions of (2) with bit shifts instead.Code:j = i << 1;
Change Val12bit to type Long in both VB and C program.Quote:
I don't get any errors now, but the Val12bit values calculated in the dll are wrong because some of them come out negative. Maybe the variable type is not correct and it should be "unsigned" or something...?
Did you make some change to the C++ code to compensate? If not you are still doing something wrong here.Quote:
Actually it was the other way round:
BufferSize = dsize\3 and not 2*dsize\3
This isn't necessary in C++ since the compiler will do it for you. Now assembler is a different story.Quote:
Originally Posted by Dave Sell
I don't think that's the problem even if it's a good idea to use 32 bit integers instead since they are faster. I think the problem with the overflow error is the bitwise OR as I mentioned in my last post.Quote:
Originally Posted by moeur
Really? Are you sure? That would be sweet if they did.Quote:
Originally Posted by moeur
The compilers know every trick in the book. That is why you can often produce faster code with C than with assembler.
Can you post some code form both for me to test? Something no doubt memory heavy?Quote:
Originally Posted by moeur
I've written a few things in C/C++ that are about 100-200ms quicker in ASM (32-bit: both).
Please, post something I can test..
Phreak
I don't have any asm code anymore.Quote:
Can you post some code form both for me to test? Something no doubt memory heavy?
I've written a few things in C/C++ that are about 100-200ms quicker in ASM (32-bit: both).
Make sure that when you compile the C code, you are otimizing for maximum speed and that you are not compiling the Debug code.
Of course if you know all the tricks too (like memory alignment issues) then you can produce asm code that is faster than C code since the C compiler is not 100% optimized, but I only know the obvious ones like Dave mentioned and hence produce slower code. That's why I don't use ASM anymore.
Actually, this is an incorrect statement. A Megabyte is not 1048576 bytes.Quote:
Originally Posted by «°°phReAk°°»
See http://helios.augustana.edu/~dr/kibibytes.html.
A Megabyte is 10^6, or 1,000,000 (a million) bytes.
A Mebibyte is 2^20, or 1,048,576 bytes.
It isn't that, I'm still getting negatives.Quote:
Originally Posted by Joacim Andersson
I haven't really been following this thread much - as I do not know C...Quote:
Originally Posted by krtxmrtz
But a negative value is simply one with the high-order bit set and touching that high order bit in multiplication will usually cause an overflow error...
Don't know if that means anything helpful!
Ya I was just getting ready to suggest that he cast his result to a signed int...Quote:
Originally Posted by szlamany
Still not working, the dll returns some negative Val12bit values. Could it have something to do with declaring the variables signed or unsigned?Quote:
Originally Posted by moeur
This is what it looks like now:
Code:'The VB side
Private Declare Sub ProcessData Lib "Mydll.dll" (DataByte As Byte, _
Val12bit As Long, _
Max12bit As Long, _
ByVal BufferSize As Long)
Dim Max12bit as Long
Dim DiskData() As Byte
Dim Val12bit() As Long
'...
'...
'...
'Later on, after the data file has been read in:
ReDim DiskData(2, dSize \ 3 - 1)
'In the data processing sub:
Dim BufferSize As Long
BufferSize = dSize \ 3
ReDim Val12bit(2*BufferSize)
Call ProcessData(DiskData(0, 0), Val12bit(0), Max12bit, BufferSize)
'...
'...
'**********************************************************************
'The C part
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
__declspec( dllexport ) void _stdcall ProcessData (char DataByte[][3],
long Val12bit[], long* Max12bit, long BufferSize)
{
long i;
long j;
*Max12bit=0;
for (i=0;i<BufferSize;i++)
{
j=i<<1; /* Multiply by 2 by doing a left shift */
Val12bit[j] = ((DataByte[i][2] & 240) * 16) | DataByte[i][0];
Val12bit[j + 1] = ((DataByte[i][2] & 15) * 256) | DataByte[i][1];
if (*Max12bit < Val12bit[j])
*Max12bit = Val12bit[j];
if (*Max12bit < Val12bit[j + 1])
*Max12bit = Val12bit[j + 1];
}
return;
}
This is why I told him to declare Val12bit to Long about 10 posts backQuote:
Originally Posted by szlamany
Just because it displays as negative is not a bad thing though - right? That's just a silly "display property" of signed integers with high-order bit set...Quote:
Originally Posted by moeur
You mean declaring Val12bit as signed int in the dll? And how about signed long? Does such a type exist?Quote:
Originally Posted by Dave Sell
OK, need more info.
Are the values that are not negative the correct values?
Are the negative values only on the even or odd Val12bit[]s?
Can you supply some data for us to work with?
In this case it's bad since he shouldn't be getting negative numbers even if they were declared as 16-bit integers.Quote:
Just because it displays as negative is not a bad thing though - right?
Actually if you are running into overflow problems, you want unsigned variables. int and long are the same thing in Win32 C++.Quote:
And how about signed long? Does such a type exist?
Well now it has finally worked!!! My last change which did the trick was declaringQuote:
Originally Posted by moeur
unsigned char DataByte[][3]
and IT WAS FAST as lightning... so I guess I'll have to include some more stuff in that dll for there's still more processing to be done...
Maybe I'm gonna need more help in the next few days. In the meantime, thanks a lot to all of you guys who've lent a hand, I feel really indebted!
I wanted to rate you guys up but it appears that I must spread some reputation around... so next time... :)
I'm glad this worked out for you - never had the need for speed like you just experienced (mainframe programmer from forever - only PC for past 4 years)...
When I do - I'll be asking you for help! :)
I've been in this boat before. I do most everything in VB. Once I had to make a routine that parsed about a MB of random text and scrape email addresses out of them. The VB appraoch could take hours. I wrote a C DLL which did the string parsing in seconds. Like so many others have said, the right tool for the right job...Quote:
Originally Posted by szlamany
Nobody is perfect (Osgood in Billy Wilder's "Some like it hot", 1959)Quote:
Originally Posted by szlamany
No language is perfect. C is impressive in its speed in cases like this problem of mine, but VB's IDE, features and debugging tools are great. But I'm afraid you'll have to ask other folks for help with C, what I used to know is only coming back to me slowly and painfully. :confused:
It turns out I must specify the full path when the dll is in the application folder. Am I missing something?Quote:
Originally Posted by Joacim Andersson
No that is correct I was wrong before.Quote:
Originally Posted by krtxmrtz
If I want to pass a boolean variable to the c dll (...ByVal MyFlag As Boolean,...), what's the corresponding data type in c?
A VB boolean is stored in a 16 bit signed integer.
I've been lucky you were on line now... thanks! :)