Solved

Using VS2005 I am writing a C++ Class to be used by VB.NET. It seems that I can't pass pointers

Posted on 2006-11-30
11
444 Views
Last Modified: 2012-06-27
I am trying to write a C++ class that I can use in VB.NET. The final product will beusing a LIB file that I don't have the source so I need to "wrap" it with C++. I can make simple data types work (ie int, douoble, char) but I can't make arrays or pointers work. I am a VB programmer by nature and I have a simple knowledge of C++ programming. I use the VisuallC++ CLR Class Library as a starting point. I was able to make the simple data parameters work. However when I try to add a pointer to a char array the sub does not show up on my list when I reference the DLL and if I force the issue I get the error "'DoIt" has a return type that is not supported or parameter types that are not suppoter".
I have included the code below
Can anyone tell me how I can make a C++ DLL that will fill an array?

---------MathFunc2dll.h------------
// MathFuncs2dll.h

#pragma once
#include <string>

using namespace System;

namespace MathFuncs2dll {

      public ref class MyMathFuncs
      {
      public:
            double Add2(double a, double b);
            double Subtract(double a, double b);
            double Multiply(double a, double b);
            double Divide(double a, double b);
            void DoIt(char *Buffer);
      };
}

---------MathFunc2dll.cpp------------
// This is the main DLL file.

#include "stdafx.h"
#include <string>
#include "MathFuncs2dll.h"

namespace MathFuncs2dll
{
      double MyMathFuncs::Add2(double a, double b)
      {
            return a+b;
      }
      double MyMathFuncs::Subtract(double a, double b)
      {
            return a-b;
      }
      double MyMathFuncs::Multiply(double a, double b)
      {
            return a*b;
      }
      double MyMathFuncs::Divide(double a, double b)
      {
            if (b==0) {
                  return 0;
            }

            return a/b;
      }
      void MyMathFuncs::DoIt(char *Buffer)
      {
      }
}

---------Module1.vb------------
Imports MathFuncs2dll.MyMathFuncs

Module Module1

    Sub Main()
        Dim mf As New MathFuncs2dll.MyMathFuncs
        Dim a As Double
        Dim b As Double
        Dim intarray(1000) As Integer

        a = 7.4
        b = 99

        Console.WriteLine("a + b = " + mf.Add2(a, b).ToString)
        mf.doit(intarray)
        Console.Write("Press <enter> to exit program")
        Console.ReadLine()

    End Sub

End Module
--------------------------------------

Thanks for any help received.
0
Comment
Question by:apmtva
  • 5
  • 4
  • 2
11 Comments
 
LVL 86

Assisted Solution

by:jkr
jkr earned 50 total points
ID: 18046349
>>but I can't make arrays or pointers work.

Check out http://support.microsoft.com/kb/205277 ("How to pass arrays and strings between Visual Basic and C functions or between Visual Basic and C++ functions by using Visual Basic 6.0") which describes the concepts behind that and explains how to do it.
0
 

Author Comment

by:apmtva
ID: 18047577
Before I go through this excersize I noticed that it said it was for VB6. I am using VS2006 .NET. Will the examples compile and work under VS2005?
0
 

Author Comment

by:apmtva
ID: 18047593
Sorry, I fat fingered the response above. I meant VS2005 not VS2006.
0
 
LVL 86

Expert Comment

by:jkr
ID: 18048144
Yes, that will still work. It's just that these issues arose earlier alread ;o)
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 18048436
Dim intarray(1000) As Integer
mf.doit(intarray)

C++/CLI prototype of doit function:

void doit(array<int>^ intarray);

If you have problem with some C++/CLI function prototype, show desired prototype in VB and I will help you to translate this to C++/CLI.
BTW, for functions shown in your sample, it is better to declare them as static, because they don't use any class members. For VB client, these fuctions will be Shared and can be used as .NET Math class functions.
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:apmtva
ID: 18048980
AlexFM

Thank yuou very much. What I needed was the ability in the C++ dll to set an array of values that vb could then use. The second part of my problem is that I need to sned a string to the c++ dll and have the c++ dll send a strng back to vb. I think I could do this with the array<char> but I am not sure how to deal with it inside of c++. I need to copy the array of charas to a simple char mString[1000] data type. How would I do this or is there a better way to deal with strings in a vb c++ inteface.

Again thanks for the array. It worked greate.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 18051679
Well, write functions that you need in VB .NET (prototypes and simplefied code) and post here, I will show you how to do this in C++/CLI. For example, you want such function:

public function GetName() as string
    return "Test"
end function

In C++/CLI this is:

public: String^ GetName()
{
    return L"Test";
}

So, instead of description, give me VB code, this is better.
0
 

Author Comment

by:apmtva
ID: 18053777
VB Code
------------------------------------------------------------------
dim strWork1 as sSring
dim strWork2 as String
dim bArray[1000] as Byte

strWork2 = "10.10.10.10"
Call SetTCPIPAddress(strWork2)

strWork1 = GetVersion()
GetBuffer(bArray)
PutBuffer(bArray)-
-----------------------------------------------------------------

C++ Code
------------------------------------------------------------------

void MyMathFuncs::StrTCPIPAddress(String^ Address)
{
  char TCPIPAddress[63];
  ???? Copy the string Address to TCPIPAddress to be used later
}
String^ MyMathFuncs::GetVersion()
{
  // Call to void Get_Version(Char *Buffer, int BufLen)

  char strWork1[1000];
  EGD_Version(strWork1, 1000);

  ???? Return strWork1
}

void MyMathFuncs::GetBuffer(array<char>^ bytearray)
{
  char buffer[1000];

  // Internal work to populate buffer

  ???? Copy buffer into bytearray
}

void MyMathFuncs::PutBuffer(array<char>^ bytearray)
{
  char buffer[1000];

  ???? Copy bytearray into buffer
}
------------------------------------------------------------------
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 18054177
void MyMathFuncs::StrTCPIPAddress(String^ Address)
{
  char TCPIPAddress[63];
  IntPtr p = Marshal::StringToHGlobalAnsii(Address);
  strcpy(TCPIPAddress, p.ToPointer());
  Marshal.FreeHGlobal(p);
}

String^ MyMathFuncs::GetVersion()
{
  // Call to void Get_Version(Char *Buffer, int BufLen)

  char strWork1[1000];
  EGD_Version(strWork1, 1000);

  return Marshal::PtrToStringAnsi(IntPtr((void*)strWork1));
}

void MyMathFuncs::GetBuffer(array<char>^ bytearray)

What is VB type that you need? .NET Char type is Unicode character - 2 bytes. C++ char byte is 1 byte. .NET type which matches to C++ char is Byte. Assuming that VB client exprcts Byte:

void MyMathFuncs::GetBuffer(array<unsigned char>^ bytearray)
{
    unsigned char buffer[1000];

    Marshal::Copy(bytearray, 0, IntPtr((void*)buffer, bytearray.Length);
}

void MyMathFuncs::PutBuffer(array<char>^ bytearray)
{
  char buffer[1000];

   Marshal::Copy(IntPtr((void*)buffer), bytearray, 0, n);  // n is array length - your program should know this
}

About last function, it is better to rewrite it by this way:

array<char>^ MyMathFuncs::GetArray()
{
  char buffer[1000];
  ...

  array<char>^ bytearray = gcnew array<char>(n);  // n is required length, <= 1000

   Marshal::Copy(IntPtr((void*)buffer), bytearray, 0, n);  

   return bytearray;
}
0
 
LVL 48

Accepted Solution

by:
AlexFM earned 450 total points
ID: 18054199
Correction: in last three functions, I mean unsigned char instead of char. You can use char as well, this requires some casting.
0
 

Author Comment

by:apmtva
ID: 18057306
Thanks for all the help. I am now able to write the DLL function in C++ to wrap the LIB that I need. However I am having an additonal problem when I referenece the routines in the LIB. I posted this as a separate problem if you want to have a look.

Thanks again.
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
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 goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

706 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

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now