digitalmars.D - Problem calling a function with a '...' parameter in a DLL
- David L. Davis <SpottedTiger yahoo.com> Dec 10 2004
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Dec 10 2004
- David L. Davis <SpottedTiger yahoo.com> Dec 11 2004
- Georg Wrede <Georg_member pathlink.com> Dec 11 2004
- David L. Davis <SpottedTiger yahoo.com> Dec 11 2004
In adding functions to my Financial project, and ran along a problem using a
"..." parameter in a Windows' DLL. The function real npv( in real rRate, ... )
works fine in a .exe build, but not as a exported function in a DLL build. So I
was wondering, if any one else has ran across this problem, and that maybe
there's a better to do this...or is this an error in which case I should report
this a an error to Walter?
Many thanks in advance! :))
Below is the command-line used to compile and run the test code, there aren't
any errors displaying...but the npv() function returns a zero. Also I've added
all the test code (npv.d, npv.def, and loader.d) below.
Command-line: Compiling and running the test code below
-------------------------------------------------------
C:\dmd>bin\dmd npv.d npv.def
C:\dmd\bin\..\..\dm\bin\link.exe npv,,,user32+kernel32,npv.def/noi;
C:\dmd>bin\dmd loader.d
C:\dmd\bin\..\..\dm\bin\link.exe loader,,,user32+kernel32/noi;
C:\dmd>loader
sLibName="C:\dmd\npv.dll", hLibWithDLL=268435456
"C:\dmd\npv.dll" is loaded
npv's dll hex addry=10003060,
Testing npv( 0.1, -10_000, 3_000, 4_200, 6_800 )= 0.00, ans=$1,188.44
sln's dll hex addry=100033AC,
Testing sln( 30000, 7500, 10 )=2250.00, ans=$2,250.00
"C:\dmd\npv.dll" is unloaded
C:\dmd>
# // -- npv.d starts --
# // npv.d - npv.dll test function call with a "..." parameter
# // To compile: C:\dmd>bin\dmd npv.d npv.def
# // Creates npv.dll
# private import std.math;
# private import std.c.windows.windows;
#
# extern( C )
# {
# void gc_init();
# void gc_term();
# void _minit();
# void _moduleCtor();
# void _moduleUnitTests();
# }
#
# extern( Windows )
# BOOL DllMain
# (
# HINSTANCE hInstance,
# ULONG ulReason,
# LPVOID pvReserved
# )
# {
# switch( ulReason )
# {
# case DLL_PROCESS_ATTACH:
# gc_init(); // initialize GC
# _minit(); // initialize module list
# _moduleCtor(); // run module constructors
# _moduleUnitTests(); // run module unit tests
# break;
#
# case DLL_PROCESS_DETACH:
# gc_term(); // shut-down the GC
# break;
#
# case DLL_THREAD_ATTACH:
# DLL_THREAD_DETACH:
# // Multiple threads not supported yet
# break;
# }
#
# return true;
# }
#
# /+
# ' NPV - Net Present Value.
# ' -------------------------------------------
# ' Excel/VBA: npv( Rate, Value1, Value2, ... )
# +/
# extern( D )
# export real npv( in real rRate, ... )
# {
# real[] rValues;
# real rSum = 0.0;
# uint uiy;
#
# rValues.length = _arguments.length;
#
# for ( uint uix = 0; uix < _arguments.length; uix++)
# {
# if ( _arguments[ uix ] == typeid( real ) )
# {
# rValues[ uix ] = *cast( real * )_argptr;
# _argptr += real.sizeof;
# }
# else if ( _arguments[ uix ] == typeid( double ) )
# {
# rValues[ uix ] = *cast( double * )_argptr;
# _argptr += double.sizeof;
# }
# else if ( _arguments[ uix ] == typeid( float ) )
# {
# rValues[ uix ] = *cast( float * )_argptr;
# _argptr += float.sizeof;
# }
# else if ( _arguments[ uix ] == typeid( long ) )
# {
# rValues[ uix ] = *cast( long * )_argptr;
# _argptr += long.sizeof;
# }
# else if ( _arguments[ uix ] == typeid( int ) )
# {
# rValues[ uix ] = *cast( int * )_argptr;
# _argptr += int.sizeof;
# }
# else if ( _arguments[ uix ] == typeid( ulong ) )
# {
# rValues[ uix ] = *cast( ulong * )_argptr;
# _argptr += ulong.sizeof;
# }
# else if ( _arguments[ uix ] == typeid( uint ) )
# {
# rValues[ uix ] = *cast( uint * )_argptr;
# _argptr += uint.sizeof;
# }
# }
#
# uiy = rValues.length - 1;
# rSum = 0.0;
#
# for ( uint uix = 0; uix < rValues.length; uix++ )
# {
# rSum += ( rValues[ uix ] /
# std.math.pow( 1 + rRate, rValues.length - uiy ) );
# uiy--;
# }
#
# return rSum;
#
# } // end real npv( in real, ... )
#
# /+
# ' SLN - Straight-Line Depreciation.
# ' --------------------------------------
# ' Excel/VBA: sln( Cost, Salvage, Life )
# +/
# extern( D )
# export real sln
# (
# in real rCost,
# in real rSalvage,
# in real rLife
# )
# {
# return ( rCost - rSalvage ) / rLife;
#
# } // end sln( in real, in real, in real )
# // -- npv.d ends --
# ; -- npv.def starts --
# LIBRARY npv
# DESCRIPTION 'test def for the npv call in a DLL'
#
# EXETYPE NT
# SUBSYSTEM WINDOWS
# CODE PRELOAD DISCARDABLE
# DATA PRELOAD SINGLE
#
# EXPORTS
# ; -- npv.def ends --
# // -- loader.d starts --
# // loader.d - DLL Loader Code
# // To compile: C:\dmd>bin\dmd loader.d
# // Creates loader.exe
# import std.stdio;
# import std.c.windows.windows;
#
# typedef real ( *pfn_npv )( in real, ... );
# typedef real ( *pfn_sln )( in real, in real, in real );
#
# int main( in char[][] args )
# {
# HINSTANCE hLibWinDLL = null;
# char[] sLibName = ""; //r"C:\dmd\npv.dll";
# char[] sPath = "";
#
# /+
# ' Set sPath to the Drive and Directory path of
# ' the executeable that is running.
# '
# ' (for example: if args[ 0 ] == "C:\dmd\loader.exe"
# ' then sPath == r"C:\dmd")
# +/
# sPath = args[0][ 0 .. std.string.rfind( args[ 0 ], r"\" ) ].dup;
# sLibName = sPath ~ r"\npv.dll";
#
# hLibWinDLL = LoadLibraryA( std.string.toStringz( sLibName ) );
# writefln("sLibName=\"%s\", hLibWithDLL=%d",
# sLibName, cast(int)hLibWinDLL );
#
# if ( hLibWinDLL <= cast(HINSTANCE)0)
# {
# writefln( "\"%s\" not found!", sLibName );
# hLibWinDLL = null;
#
# return -1;
# }
#
# writefln("\"%s\" is loaded", sLibName );
#
# pfn_npv npv =
# cast(pfn_npv)GetProcAddress( hLibWinDLL, "D3npv3npvFeYe" );
# writefln( "npv's dll hex addry=%X,
# Testing npv( 0.1, -10_000, 3_000, 4_200, 6_800 )=%5.2f, ans=$1,188.44",
# cast(long)npv, npv( 0.1, -10_000, 3_000, 4_200, 6_800 ) );
#
# pfn_sln sln =
# cast(pfn_sln)GetProcAddress( hLibWinDLL, "D3npv3slnFeeeZe" );
# writefln( "sln's dll hex addry=%X,
# Testing sln( 30000, 7500, 10 )=%5.2f, ans=$2,250.00",
# cast(long)sln, sln( 30000, 7500, 10 ) );
#
# writefln("\"%s\" is unloaded", sLibName );
#
# FreeLibrary( hLibWinDLL );
#
# return 0;
#
# } // end int main()
# // -- loader.d ends --
David L.
-------------------------------------------------------------------
"Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"
Dec 10 2004
David L. Davis wrote:In adding functions to my Financial project, and ran along a problem using a "..." parameter in a Windows' DLL. The function real npv( in real rRate, ... ) works fine in a .exe build, but not as a exported function in a DLL build. So I was wondering, if any one else has ran across this problem, and that maybe there's a better to do this...or is this an error in which case I should report this a an error to Walter? Many thanks in advance! :))
This is just a shot in the dark, since I have *0* DLL experience. Maybe the code in the DLL uses different typeid() data than the executable which links to it? I would try putting a final "else" block in your function, which says, "I don't recognize the type, this is an error."
Dec 10 2004
In article <cpclti$1uue$1 digitaldaemon.com>, Russ Lewis says...David L. Davis wrote:In adding functions to my Financial project, and ran along a problem using a "..." parameter in a Windows' DLL. The function real npv( in real rRate, ... ) works fine in a .exe build, but not as a exported function in a DLL build. So I was wondering, if any one else has ran across this problem, and that maybe there's a better to do this...or is this an error in which case I should report this a an error to Walter? Many thanks in advance! :))
This is just a shot in the dark, since I have *0* DLL experience. Maybe the code in the DLL uses different typeid() data than the executable which links to it? I would try putting a final "else" block in your function, which says, "I don't recognize the type, this is an error."
with a message, and I can clearly see that it's got the number of parameters being passed in right, but somehow the typeid() is unknown / wrong. For now I'll just use a real[] array for the DLL build, but it would've been nice to have a bit more feed back from the forum. I was really hoping for more help on this "..." parameter subject, than what can be found in the DigitalMars D html help files. ------------------------------------------------------------------- "Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"
Dec 11 2004
In article <cpfobd$fbc$1 digitaldaemon.com>, David L. Davis says...bit more feed back from the forum. I was really hoping for more help on this "..." parameter subject, than what can be found in the DigitalMars D html help files.
Well, this is an exceptional time for D. "Real Soon Now" version 1.0 is coming out. That means Walter is (my condolences to his Family) over- worked, most of the other Gurus are busy fixing, suggesting, or creating least-lines-proofs of bugs -- not to mention that nobody has even started to ponder over updating the existing documentation to a form suitable for a Release! My bet is, 2 months after D 1.0 is out, this forum might really be the place to ask things. But definitely not before that.
Dec 11 2004
In article <cpfu29$jmr$1 digitaldaemon.com>, Georg Wrede says...In article <cpfobd$fbc$1 digitaldaemon.com>, David L. Davis says...bit more feed back from the forum. I was really hoping for more help on this "..." parameter subject, than what can be found in the DigitalMars D html help files.
Well, this is an exceptional time for D. "Real Soon Now" version 1.0 is coming out. That means Walter is (my condolences to his Family) over- worked, most of the other Gurus are busy fixing, suggesting, or creating least-lines-proofs of bugs -- not to mention that nobody has even started to ponder over updating the existing documentation to a form suitable for a Release! My bet is, 2 months after D 1.0 is out, this forum might really be the place to ask things. But definitely not before that.
Georg Wrede: Thanks for the reply. Yeah, I agree with you that this is a great time with D v1.0 just around the corner to be programming in D, and that everyone here has been pretty busy. I too, feel for Walter...he's been working pretty hard these past few years on the D compiler / Phobos runtime library. Again thanks for the reply. David L. ------------------------------------------------------------------- "Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"
Dec 11 2004








David L. Davis <SpottedTiger yahoo.com>