?
Solved

Complex C DLL Callback function Struct

Posted on 2003-02-25
11
Medium Priority
?
391 Views
Last Modified: 2010-04-07
I'm trying to translate some c work into VB and of course the C code uses a C style DLL which I have to match in VB.  I know that i need to make Declare statements to match the calls, but what is really getting me is a parameter of one of those calls.

I will list the C struct and call below, then if anyone can help me translate this into VB I would really appreciate it.


// C - Structure
typedef struct
{
   void (*onProgress) (long SomeLong, int i_progress);
   void (*onResult) (long Result, const char* TextResult);
} CALLBACKSTRUCT

//How it is called in C++
CALLBACKSTRUCT MyNewStructure;

MyNewStructure.OnProgress = MyOnProgress;  // MyOnProgress is the name of a function call in C++
MyNewStructure.OnResult = MyOnResult;

//Finally it is being used in another DLL Call...

return = CreateProgress(&MyNewStructure);


Any and all help would be appreciated!!
0
Comment
Question by:Shaka913
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
11 Comments
 
LVL 5

Accepted Solution

by:
JMoon5FTM earned 600 total points
ID: 8018490
Visual Basic doesn't support storing procedures in variables, so what you'll have to do is:

1)  Type both structure members as Long.

Type CallbackStruct
   OnProgress as Long
   OnResult as Long
End Type

2)  Use the addressof operator to extract pointers to the callback functions.

This should work, but doesn't:

Dim MyStruct as CallbackStruct
MyStruct.OnProgress = addressof MyOnProgress
MyStruct.OnResult = addresssof MyOnResult

Visual Basic only recognizes addressof in a function call - the result of addressof can't be stored directly in a variable.  So, you have to do this:

Dim MyStruct as CallbackStruct
MyStruct.OnProgress = DoNothing(addressof MyOnProgress)
MyStruct.OnProgress = DoNothing(addressof MyOnResult)

Private Function DoNothing(byval Number as Long) as Long
   DoNothing = Number
End Function

3) Declare and call the DLL function as usual.
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 8018611
hearing...
0
 
LVL 3

Expert Comment

by:Da_Weasel
ID: 8021317
Couldn't you do this for the addressof functions

Dim MyStruct as CallbackStruct
With MySruct
  .OnProgress = CLng(addressof MyOnProgress)
  .OnResult   = CLng(addressof MyOnResult)
End With

??
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 3

Expert Comment

by:Da_Weasel
ID: 8021328
seems like a waste and a pain to create a function that just the same thing basicly as a builtin VB function....
0
 
LVL 3

Expert Comment

by:Da_Weasel
ID: 8021363
BTW CLng() is basicly the VB style type cast for Long var types
Here is a list of Type Conversion Functions:
CBool(expression)
CByte(expression)
CCur(expression)
CDate(expression)
CDbl(expression)
CDec(expression)
CInt(expression)
CLng(expression)
CSng(expression)
CStr(expression)
CVar(expression)

0
 
LVL 5

Expert Comment

by:JMoon5FTM
ID: 8026472
CLng would be a less efficient solution, since it coerces its input to a variant, and then checks then checks the vartype to determine what conversion is necessary.  But, if I'd thought of it, I'd probably have used it anyway - the performance isn't that big of a deal here.  On the other hand, if you're doing this within a loop within a loop, the difference may be noticeable on a slow machine.
0
 
LVL 3

Expert Comment

by:Da_Weasel
ID: 8026822
Do you have any supporting docs that reference the steps involved the conversion in these functions...?   Would be interested in reading this.  It wasn't really performance issue though, it was more about having easy to maintain code.

But lets examine the 2 methods.

Type Conversion Functions benifits:
1. Compiled inline meaning that it doesn't have the overhead of a Procedure call.
2. Can be used to with out any additional code to maintain.


Using the DoNothing() fucntion benifits:
1. ummmm....i just can't think of any....
0
 
LVL 5

Expert Comment

by:JMoon5FTM
ID: 8033996
Yeah, right...

First of all, CLng is NOT compiled inline.  There are some conversion functions that are (such as Val), but CLng is not among them.  I can't remember the source for this information, but I've done the performance tests myself and there's no way CLng is inline.  When I find the supporting docs, I'll be sure to point you to them.

As for the implementation of CLng, these are from the MS site:

msdn.microsoft.com/library/en-us/ vbceide/htm/function_12.asp - "This function converts an expression to a Variant of subtype Long."

msdn.microsoft.com/library/en-us/ script56/html/vsfctclng.asp - "Returns an expression that has been converted to a Variant of subtype
Long."

Yes, neither of these applies directly to the standalone VB for Win32, but on a platform as limited as Windows CE it seems unlikely they would alter the function to make it less efficient.  Anyway, there's better proof, and when I remember where I found it, I'll get back to you.
0
 
LVL 3

Expert Comment

by:Da_Weasel
ID: 8035005
I was looking at the VB.Net docs when I read about the Type Convertion Fucntions being inline.  You might be right about the inline issue, I can't seem to find any docs that discuss this issue with any specifics

What kind of testing did you do though?  I just made some real simple test.
The difference in speed doesnt become noticable until its looped at least 100,000 times in IDE, 10,000,000 in P-Code and 1,000,000,000 in Native Code.
Here are some test results, all values are in approximate seconds with a 1 second variance and were run on a 2.4Ghz machine with 512MB RAM:

100,000,000 iterations
  IDE
    CLng 3 seconds
    DoNothing 21 seconds
  P-Code
    CLng 2 seconds
    DoNothing 18 seconds
  Native Code
    CLng 1 seconds
    DoNothing 1 seconds
2,000,000,000 iterations
  IDE
    CLng 59 seconds
    DoNothing 426 seconds
  P-Code
    CLng 37 seconds
    DoNothing 290 seconds
  Native Code
    CLng 4 seconds
    DoNothing 10 seconds

Long story short, CLng is faster, but either way speed is not an issue, since there is only a 6 second difference when its looped 2 billion times in Compiled Native Code.  I mean how often do you need to do type convertion 2 billion times in a row?!

The real issue is:  Why reinvent the wheel, especially when your wheel isnt as good as the original?
What happens when other issues like this come up with other data types?  Do you make more fuctions?  What do you call them?  DoNada for Int? DoZilch for Double?  When you come back to look at this code in a year, are you gonna remember that DoNothing actually 'DoesSomething' and what that something was?
0
 
LVL 5

Expert Comment

by:JMoon5FTM
ID: 8041996
I don't know about those numbers...but it doesn't really matter, since I already agreed with you earlier that I wouldn't have re-invented the wheel if I'd remembered there was already a VB function I could pass a long to and have it come back unchanged.

Since we're trying for optimal performance, I suppose that DoNothing ought to receive its Number ByRef...but again, who'll notice the difference?
0
 
LVL 3

Expert Comment

by:Da_Weasel
ID: 8042262
my test were done with 'Number' being passed 'ByRef'...
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…
Suggested Courses

765 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