Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 473
  • Last Modified:

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

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
apmtva
Asked:
apmtva
  • 5
  • 4
  • 2
2 Solutions
 
jkrCommented:
>>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
 
apmtvaAuthor Commented:
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
 
apmtvaAuthor Commented:
Sorry, I fat fingered the response above. I meant VS2005 not VS2006.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
jkrCommented:
Yes, that will still work. It's just that these issues arose earlier alread ;o)
0
 
AlexFMCommented:
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
 
apmtvaAuthor Commented:
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
 
AlexFMCommented:
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
 
apmtvaAuthor Commented:
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
 
AlexFMCommented:
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
 
AlexFMCommented:
Correction: in last three functions, I mean unsigned char instead of char. You can use char as well, this requires some casting.
0
 
apmtvaAuthor Commented:
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

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.

  • 5
  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now