calling a dll function that receives/returns a double from VB

Posted on 2003-03-02
Medium Priority
Last Modified: 2010-04-01

im trying to pass a double type to a dll function that returns a double in VB. i get the error "bad Dll naming convention".

heres the VB function declaration:

Declare Function fnCPS_DateFormat Lib "CPS_DateFormat.dll" Alias "_fnCPS_DateFormat@8" (dblDate As Double) As Double

and heres the C++ function declaration:
extern "C" __declspec(dllexport) double WINAPI fnCPS_DateFormat(double dblDateDiff);

if the types are changed to int it works fine. is there something i need to do for i to work with doubles (pretty much 64 bit signed integers)
Question by:sheslop
  • 2
LVL 49

Accepted Solution

DanRollins earned 400 total points
ID: 8055913
>> pretty much 64 bit signed integers
perhaps the same size, but not at all the same otherwise.

Have you made an explicit declaration in the DEF file for the DLL?  I think you can use
=-=-=-=-=-=-=-=-=-=-=-=- the .DEF file is below this line
; CPS_DateFormat.def : Declares the module parameters for the DLL.

LIBRARY      "CPS_DateFormat"
DESCRIPTION  'CPS_DateFormat Windows Dynamic Link Library'

    ; Explicit exports can go here
    fnCPS_DateFormat  @1
=-=-=-=-=-=-=-=-=-=-=-=- the .DEF file is above this line

Then in VB:
Declare Function fnCPS_DateFormat Lib "CPS_DateFormat.dll" (ByVal dblDate As Double) As Double

-- Dan
LVL 49

Expert Comment

ID: 8055917
However, I did not test that against VB.  -- Dan
LVL 12

Assisted Solution

Salte earned 400 total points
ID: 8058418
Note that double and 64 bit int are very different:

A double is like a struct and is declared as such:

The high bit (bit 63) is sign bit, if 0 the value is positive if 1 the value is negative (this is the same as for signed 64 bit integer).

The next 11 bits (52..62) are an integer giving the exponent. This exponent has a bias of 0x3ff.
The exponent with all bits 0 (0x000) is special and so is the exponent with all bits 1 (0x7ff), the other values are regular exponent values and the actual exponent is the exponent field - bias, so 0x3ff means exponent is 0, 0x3fe means exponent is -1, 0x400 means exponent is 1, 0x401 means exponent is 2 etc.

The remaining bits (0..51) are mantissa, if exponent is all bits 0 (0x000) the mantissa holds the bits scaled by an exponent of -0x3ff, i.e. the mathematical value of the double is then Mantissa >> 0x3ff However, the mantissa itself is considered to be of the form 0.xxxxxxxx where the mantissa bits are so if you instead consider the bits to be an integer value it is Mantissa >> (0x3ff + 52) where Mantissa is a 52 bit integer. This is used to represent very small values.

If exponent is all bits one (0x7ff), the double value is one of the values (NaN, +infinity or -infinity). The mantissa is used to differentiate between Nan or the infinities and the sign bit is used to represent + or - infinity.

If exponent is neither all bits one or all bits 0 then the mantissa is used to hold the mantissa of the number in the following representation:

0.1xxxxxxxxxxxxx...xx where the x's are the 52 bits of the mantissa. This gives a value in the range 0.5 <= M < 1.0 and the result of the double value is then:

sign * M * 2^(exponent - 0x3ff);

Again you can instead consider the mantissa to be an integer that is scaled by -53, if so we have to add the high bit explicitely so:

(0x001000000000000LL + (DblVal & 0x000fffffffffffffLL)) * pow(2,((DblVal >> 52) & 0x7ff) - 0x3ff - 53);

and then if sign bit is set we simply negate this value.

Of course, in real code you never do any of this since the double type handle this stuff on quite well on its own.

The idea is that double and 64 bit int are very different types even if their size is the same, for example the value 1.5 represented as double is:

step 1. sign bit is 0.
step 2. scale value to become less than 1.0 and greater or equal to 0.5:
      1.5 * 2^0
      0.75 * 2^1
      0.75 == 0.1100000....
step 2:
      remove the highest bit which is always 1.
      0.25 == 0x010000000

step 3: find exponent: 0x3ff + 1 == 0x400

step 4: the floating point value is:

      6 666 5555 5555 5
      3 210 9876 5432 1
      s xxx xxxx xxxx mmmm mmmm mmmm mmmm mmmm mmmm...
      0 100 0000 0000 1000 0000 0000 0000 0000 0000...

      40 08 00 00 00 00 00 00 00

so 1.5 is represented by the value 0x4008000000000000LL

If you read that bit pattern as a 64 bit integer it becomes the value 4,613,937,818,241,073,152. A completely different value.

Just because they are the same size in bits doesn't mean you can consider the two types to be the same.

If so you could consider a coordinate of two 16 bit integers to be the same as a 32 bit integer, they usually are interpreted as very different values even though they are both 32 bits.

If two data types are the same number of bits you can in some cases treat them the same. These cases always depend on the fact that you do not attempt to interpret the value but only copy it bit by bit to some other location etc. As soon as you inspect the bits to interpret the value - as in the case of attempting to format the value it is an error to treat the types as if they were the same.

LVL 30

Expert Comment

ID: 9372386
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:
Split between [DanRollins] and [Salte]
Please leave any comments here within the next seven days.


EE Cleanup Volunteer

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

615 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question