Passing argument ito dll call in vb .net

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • abghosh
    New Member
    • Feb 2010
    • 7

    Passing argument ito dll call in vb .net

    In my vb.net code I want to call a dll file created by Qt4.
    Now everything works fine untill and unless I pass some string argument to the function.

    Here is the function in dll file:
    Code:
    const char* QtEngineDll::randInt(char url[])
    {
        QString result;
        /*QTextCodec *codec = QTextCodec::codecForName("UTF-8");
        QByteArray d = codec->fromUnicode(url);
        result= QString(d.length());
        QString fileName = QDir::currentPath() + "/Test.txt";
        QFile file(fileName);
        file.open(QIODevice::Append | QIODevice::Text);
        file.write(result + "\n");*/
        return result;
    }
    and here is how I am calling it in vb.net:

    Code:
    <DllImport("G:\test\debug\test.dll", _
            SetLastError:=True, CharSet:=CharSet.Unicode, _
            ExactSpelling:=True, _
            CallingConvention:=CallingConvention.StdCall)> _
        Private Shared Function randInt(ByVal u As StringBuilder) As StringBuilder
        End Function
    When the function returns some constant value, say if i put result = "Abhijit" then it returns the value properly. But if I want result to return value url the it is returning some garbage values.

    Thanks in advance for any help.
  • !NoItAll
    Contributor
    • May 2006
    • 297

    #2
    Well, I'm a bit confused because this is not all vb. Your function is c#, but your pInvoke is vb. I'll assume you are not trying to mix these in your project or you would have lots of other problems than just what you have described...

    On the surface it does look like you have declared the DLL function with u as a stringbuilder object, but in your call to it you are passing in a char array. From what I understand this shouldn't work at all.
    If you are starting with a char array, and need a char array back you will need to do the proper conversion to a stringbuilder and then pass the stringbuilder to the DLL function, and then turn the stringbuilder returned back to a char array as these types are not interchangeable .

    Comment

    • abghosh
      New Member
      • Feb 2010
      • 7

      #3
      Hi NoItAll

      You are right. Not all codes are in vb. As I have mentioned the dll is created using qt4 and the dll call is made using vb.net.

      Can you pls explain a bit more on your comments. Even in place of stringbuilder i pass String argument then also it is not working.


      Any way thanks for ur reply.

      Comment

      • !NoItAll
        Contributor
        • May 2006
        • 297

        #4
        A string is not a Stringbuilder. A String in .NET is an immutable object. Any time you make a change to a string you are actually creating a new string entirely. On the other hand, a stringbuilder is mutatable. The DLL wants you to pass it a stringbuilder object, nothing else. So - you are starting with a char array that contains your url. You need to convert it to a stringbuilder and then pass the stringbuilder to the DLL.
        Code:
        Dim strb As New StringBuilder
        strb.Append(New String(URL))    'URL is your original char array containing the URL...
        now you can pass strb into your DLL...
        Code:
        Dim MyURLstrb as new StringBuilder
        MyURLstrb=randInt(ByVal strb As StringBuilder)
        the DLL will return a string builder object (the MyURLstrb created above) which, I assume, you want to become a char array:
        Code:
        Dim MyURLCharArray() As Char = MyURLstrb.ToString.ToCharArray
        Now you have a char array called MyURLCharArray that is the result of your DLL.

        Comment

        • abghosh
          New Member
          • Feb 2010
          • 7

          #5
          Nope it didn't work either. Let me give my code here:
          VB code for calling the dll function
          Code:
          Private Sub getData(ByVal rowIndex As Integer)
                  Dim Message As String = "Sumana"
                  Dim temp As New StringBuilder
                  temp.Append(New String(Message))
                  Dim res As New StringBuilder
                  res = _ZN11QtEngineDll7randIntEPKc(temp)
                  Dim x() As Char = res.ToString
                  Try
                      logText.AppendText(vbCrLf & x)
                  Catch
                      Beep()
                      MsgBox("Cannot read from DLL.")
                  End Try
              End Sub
          
              <DllImport("G:\test\debug\test.dll", _
                  SetLastError:=True, CharSet:=CharSet.Ansi, _
                  ExactSpelling:=True, _
                  CallingConvention:=CallingConvention.Cdecl)> _
              Private Shared Function _ZN11QtEngineDll7randIntEPKc(ByVal u As StringBuilder) As StringBuilder
              End Function
          This is the Qt4 code for making the dll file.
          Code:
          const char* QtEngineDll::randInt(const char* test)
          {
              const char* ur = test;
              QString result = QString(ur);;
              QString fileName = QDir::currentPath() + "/Test.txt";
              QFile file(fileName);
              file.open(QIODevice::Append | QIODevice::Text);
              file.write(result + "\n");
              return result;
          }
          Just a string output will be fine. But it is only giving me some garbage value.

          Comment

          • !NoItAll
            Contributor
            • May 2006
            • 297

            #6
            Well - I'm not familiar with the syntax of the dll code - I don't know exactly what a QString is...
            But - it looks like you may be taking a char array in as a paremeter and returning a string. Why is the PInvoke creating the instance using a stringbuilder and returning a stringbuilding? This code is too confusing for me I'm afraid.

            I think you need to get a handle on the data types - what does the dll need and use, and what does it return. match those data types going in and for the assginment of the return value. Until you get that straight there's little hope of getting anything other than garbage. Perhaps someone familiar with QT4 can help you - I don't know what it is.

            Comment

            • abghosh
              New Member
              • Feb 2010
              • 7

              #7
              Hi
              Actually whatever argument I am passing its not working. E.g. suppose I am passing an integer argument (say 8) but a constant integer 1 is being passed every time.

              So I require help on passing argument to this.

              Comment

              • !NoItAll
                Contributor
                • May 2006
                • 297

                #8
                Huh? I don't understand you at all now. Please try to word your question in a way that can be understood.

                E.g. suppose I am passing an integer argument (say 8) but a constant integer 1 is being passed every time.
                - this makes no sense to me at all. Perhaps I'm being thick - but this statement strikes me as jibberish?

                To review:
                When you instantiate a DLL you set it up to accept parameter(s) of specific data types and typically to return a value of a specific data type. When you use the DLL you have to pass it those parameters using the EXACT data type it expects, and provide a return variable of the EXACT data type the DLL will return. You can not return an integer into a string, or a char array into an integer, or a string into a stringbuilder. When calling a DLL make sure you fully understand what the DLL needs, and then create the parameters and variable of the same data types it requires. Failure to do that will usually result in an exception, or sometimes the DLL will still place values into the variable, but they will be garbage.

                MyDLL(Variable A as Pig) as Cow

                MyDLL requires you to pass a variable as a Pig and it will return a Cow.

                Dim MyPig as Pig = pigtypedata
                Dim MyCow as Cow = nothing

                MyCow = MyDLL(MyPig)

                If I try something like this:

                Dim MyString as String = "Pig"
                Dim MyInteger as Integer = 1

                MyString = MyDLL(MyInteger )

                I will wind up with either an exception or garbage since the DLL MUST have a PIG for a paremeter and only can return a COW. A PIG is not a string and a COW is not an integer.

                Comment

                • abghosh
                  New Member
                  • Feb 2010
                  • 7

                  #9
                  Thanks for your suggesstion.
                  In my last reply what I want to convey is that:

                  Case 1:
                  # Dll function takes string as an argument and returns string as the result.
                  In this case if I call the function like:

                  Code:
                  <DllImport("G:\test\debug\test.dll", _ 
                          SetLastError:=True, CharSet:=CharSet.Ansi, _ 
                          ExactSpelling:=True, _ 
                          CallingConvention:=CallingConvention.Cdecl)> _ 
                      Private Shared Function _ZN11QtEngineDll7randIntEPKc(ByVal u As String) As String
                      End Function
                  
                  Dim res As String = _ZN11QtEngineDll7randIntEPKc("MyFun")
                  MsgBox(res)

                  Case 2:
                  # Dll function takes Integer as an argument and returns Integer as the result. (P.S: this is a different dll function)
                  In this case if I call the function like:

                  Code:
                  <DllImport("G:\test\debug\test.dll", _ 
                          SetLastError:=True, CharSet:=CharSet.Ansi, _ 
                          ExactSpelling:=True, _ 
                          CallingConvention:=CallingConvention.Cdecl)> _ 
                      Private Shared Function _ZN11QtEngineDll7randIntEi(ByVal u As Integer) As Integer
                      End Function
                  
                  Dim res As Integer = _ZN11QtEngineDll7randIntEi(25)
                  MsgBox(res)
                  Hope now I am able to convey the way I am calling DLL function.

                  In both the cases the output from the dll function call is well and good enough. But the main problem arises when passing the argument to the function.

                  In case 1, some garbage value is passed and in case 2 1 is passed indifferent of what I want to pass.

                  Comment

                  Working...