473,472 Members | 2,168 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

VBA to C Crossover

NeoPa
32,556 Recognized Expert Moderator MVP
Overview

At their hearts, Visual Basic type languages and c type languages are quite different. In visual Basic type languages you deal with data at a step removed, whereas c type languages leave you down and dirty with the data and how it's referenced. Let me try to explain what I mean by that. To simplify the explanations below I'll refer to Visual Basic type languages simply as VB, and equally the c type languages simply as C. I appreciate that c type languages generally use lower case for such references but here I'm referring to a whole swathe of languages grouped together so I'll proceed to use the upper case for it.


Explanations

In VB a String value is referenced as a single object. The name of the variable references it as an indivisible item. In C, on the other hand, a string is handled by a pointer to the first character of that string. Unless you use the pointer indicator (* in c) any reference to the value of the variable returns, not any character of the string, but simply the address where these characters may be found in sequence in memory. Also in C, the length of a string is determined by the position of the first NullChar character relative to the start position of the string. I use NullChar to mean a single character position with a value of zero. This is quite different from the concept of Nulls as such, whose explanation doesn't fit here. In VB a String is stored as a list of characters but with a separate Word (16-bit) value representing the length of the string. The character list thus has no need for the extra NullChar at the end.

At this point I'll go into a little explanation of how procedures are called in VB and C. Please feel free to comment with corrections if I get any of the details wrong. It's been a long time since I did any serious work in C and never needed as full an understanding in VB. So, here goes...

The first idea to understand is how the Stack is used to pass values and variables to the called procedure from the calling code. To understand this it is necessary to appreciate the difference between those parameters that are used exclusively within the called process itself, and those that are used there but whose resultant values should also be available to the calling one. In it's simplest form those which are needed back again are passed as pointer values and those which aren't, where practical, are passed as the values themselves.

So, in C you may see something like :
Expand|Select|Wrap|Line Numbers
  1. dword myfunc(dword x, dword* y, char* z)
x is a 32-bit numeric value. This is PUSHed onto the Stack first as the value of x.
y is also a 32-bit numeric value - but the procedure is expecting the address of y rather than its value. The address is thus PUSHed onto the Stack next.
z is a String or char pointer. This address is PUSHed onto the Stack last.

In VB you may see something like :
Expand|Select|Wrap|Line Numbers
  1. Function MyFunc(ByVal lngX As Long, ByRef lngY As Long, ByVal strZ As String) As Long
lngX is a 32-bit numeric value. This is PUSHed onto the Stack first as the value of lngX.
lngY is also a 32-bit numeric value - but as it's ByRef the procedure is expecting the address of lngY rather than its value. The address is thus PUSHed onto the Stack next.
strZ is a String. The address is PUSHed onto the Stack last.

I won't go into how literal values (or others defined such that they're not to be updated) are handled in any detail but the compiler ensures that no changes can be made to values which are passed by address even though, otherwise, that could be possible.

When the called procedure receives control it will POP the values off the stack in reverse order and use them as specified in the declaration.

By now you will already have noticed that C treats strings differently so in VB, if you want to use a procedure designed for C, you have to prepare an existing String before passing it across by adding a NullChar at the end. For returned String values you may sometimes be given a length separately, but you'll always have to use something like Left() to assign the correct String value to a variable.


Rules

This is where I'll indicate how to declare something in VB when, as is commonly the case, you're dealing with standard (Non-VB) libraries that expect to interface with C code. An example of the sort of procedure I'm talking about would be RegEnumValue Function. Notice the syntax has a middle column that indicates what type of information is expected. Below I'll try to indicate for each type how it should be called from VB.

NB. Each also has an indicator in the left column which also needs to be taken into consideration as this affects how it needs to be used. You may notice that all that include Out have C Types that start LP - for Long Pointer. This is because the procedure changes the value pointed to and, of course, both caller and callee have access to the same memory pointed to.

Expand|Select|Wrap|Line Numbers
  1. C Type      VB Type         Desc                        Explanation
  2. HKEY                        Hive Key                    Same as DWORD
  3. DWORD       ByVal Long      Double Word                 32-bit value itself
  4. LPTSTR      ByVal String    Long Pointer to String      32-bit pointer to first char of String
  5. LPDWORD     ByRef Long      Long Pointer to Long        32-bit pointer to 32-bit value
  6. NULL        ByVal Long      Long Pointer to anything    *See below
  7. *This is a special case so is treated the same as a DWORD with a value of 0.  This is interpreted as a pointer to 0 - or Null Pointer.
When you pass any form of String across you need to ensure that it's terminated with a NullChar. More importantly, always pay very careful attention to any parameters used for specifying string lengths - even, and especially, for maximum lengths of String values to be returned. When passing a String parameter that the called procedure is expected to fill itself, remember it will expect a buffer to be available into which it can copy its value. It's critical, if you don't want your whole project to crash and burn, that you prepare a space in advance that's large enough to handle whatever can be thrown at it. Sometimes procedures have a parameter whereby you can specify the maximum length of string it should be allowed to use but other times they may not. Be conservative and ensure you always allow plenty. A good way to do this in VB is to say strX = Space(255) before you try to pass it across.


Conclusion

While this appears to be very awkward and complicated, by following some of the simple rules above we can use procedures that were built to interface with C from within VBA.
Feb 3 '18 #1
0 3747

Sign in to post your reply or Sign up for a free account.

Similar topics

2
by: John A. Bailo | last post by:
I wrote two windows services that are slight variations on each other. I changed the assembly name ( .exe ) and the namespace within each other. Both have some static methods that share the...
10
by: cashdeskmac | last post by:
I have been studying C# for 18 months via a distance-learning course, but having just got my first IT job, I will be using only VB .NET as the programming language. The syntax is very similar,...
0
by: robert | last post by:
I'm looking for an efficient optimizer on a noisy high-dimensional and costly function. My own GA hack seems to be somewhat stiff and I find me trying too much around with different cooling speeds...
2
by: Water Man | last post by:
Hi All, I connect two computer with one network cable. They used NIC(Etharnet network card). I can't chat these computers in cmd. I mean, I can't use net send commond. So I want to chat these...
10
by: Carramba | last post by:
Hi! I have two integers and I want exchnge they bits from certain position (Crossover) as follows: int main() unsigned int crossPos; unsigned int b, b1; unsigned int value1, value2;...
2
by: jrmemon007 | last post by:
I have 2 computers, one is a acer laptop and the other is a desktop. i want to connect the computers without a router, and only using the crossover cable. After some hardwork the laptop establishes a...
10
Rabbit
by: Rabbit | last post by:
I only know a little bit about networking so... I have 2 routers, 5 computers and a cable modem. I thought all I had to do was plug the cable modem into the WAN slot of one router. Connect a...
11
by: DumRat | last post by:
Hello, I am making this TSP solver using a genetic algorithm. And I ran into this problem and I can't work it out. The problem is, I pass the two parent genes and the two child genes into...
1
by: Johannes Bauer | last post by:
Hello group, I'm having a seemingly simple problem. I want to generate a hierarchy of modules, like this one: GenerationScripts/ GenerationScripts/dhcp GenerationScripts/bind9 And the...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.