?
Solved

passing VB.NET Strings to VC dll.

Posted on 2004-03-27
10
Medium Priority
?
854 Views
Last Modified: 2008-02-01
I want to pass a VB.NET string variable to my VC dll. The function in dll uses LPSTR.  why is it that i have to set the string to some initial value and then pass this string. This style works, but it is not a proper one. for example -

Dim str as String
str = "11111111111"

if i don't do this, i get an error of Nullreference ptr. this style is quite an improper one. if the new value put by the DLL is greater than the size specified, i.e., "11111111111",  then that value is truncated to the VB String size. if the new value filled in by DLL is less than initial size of "11111111111", then that much goes as a waste.

is there any other method to do this stuff. i've tried interop marshal concept  using Intptr. that too fails. Intptr works fine when i've a string inside a structure. but if that string goes individually, IntPtr fails. i don't understand why it fails here.

regards
0
Comment
Question by:rahul_milo
[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
  • 5
  • 3
  • 2
10 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 400 total points
ID: 10694997
Consider the following Dll function:

// Function gets const pointer to string
void CFunction(char* p)                    // == LPSTR
{
    MessageBox(NULL, p, NULL, MB_OK);
}

To call it from C#:

[DllImport ("ServerDll.dll")]
public static extern void CFunction(IntPtr p);

String s = "11111111111";

// allocate string on unmanaged heap
IntPtr ptr = Marshal.StringToHGlobalAnsi(s);

CFunction(ptr);

// free memory
Marshal.FreeCoTaskMem(ptr);

If C function gets UNICODE string paraneter (WCHAR*), use Marshal.StringToHGlobalUni. I hope you can translate this code to VB .NET without problems.
0
 
LVL 6

Expert Comment

by:KarunSK
ID: 10696437
It is not correct to pass a String type to a DLL if the DLL is going to change the value of the string. This is because String is an immutable object. So even if you are able to change the value (of which I am not sure), t may have other unwanted side effects.

You can use a StringBuilder or byte array in its stead. See if this link is helpful:

http://experts-exchange.com/Programming/Programming_Languages/Dot_Net/Q_20930937.html
0
 

Author Comment

by:rahul_milo
ID: 10702739
Thanks Alex,

It was gr8 as i cud declare a String s = "1" only use the same for all my config parameters. It worked fine and also returned the value greater than 1 byte.
 
what KarunSK has suggested that strings are immutable and their value cannot be changed inside a DLL. right or wrong. bcoz i'm able to do this without getting any error. may be an error creeps in some other time.

rahul.
0
Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

 
LVL 48

Expert Comment

by:AlexFM
ID: 10702809
Show your C function code. My way works to pass read-only string to Dll. If you change it, original string is not changed.
0
 

Author Comment

by:rahul_milo
ID: 10702863
Karun,

I must say, this was an add to my knowledge. lovely point made. my ques - if strings r immutable, then how come they r changed at the first instance. u said, may be later this may cause errors.

anyways, yr link was good to make me learn more on strings.
0
 

Author Comment

by:rahul_milo
ID: 10702902
Karun,

I was just going thru the MSDN link given by u. man, it was an eye opener. thanks. i'm getting a lot of callback problems. i hope avoiding string passing will stop this callback errors. i think the heap is getting destroyed bcoz of string passing. thanks

rahul
0
 

Author Comment

by:rahul_milo
ID: 10703201

__declspec(dllexport) int get_config(LPSTR key, LPSTR val)
{

      if ((idx=searchkey(key))<=Failure)
        ERROR ------
      else
          sprintf(val, "%s", key_arr[idx].ptr);   // ptr is a char*
                  or
          sprintf(val, "%d", *((int*)key_arr[idx].ptr));  // it'll be like this for integers.
}


0
 

Author Comment

by:rahul_milo
ID: 10703265
KarunSK,

There is some problem with the StringBuilder i used. There is no error in the code. but the value returned is not up to the mark. If u can see the same, i'll be grateful.

This is my VB function declaration -
Public Declare Function nyget_config Lib "c:\my_comm\mycomm.dll" (ByVal key As String, <System.Runtime.InteropServices.MarshalAsAttribute(Runtime.InteropServices.UnmanagedType.LPWStr)> ByVal value As System.Text.StringBuilder) As Integer
-----StringBuilder goes as ByVal in the prototype.-----------------------------

This function in the DLL wud search the KEY (1st parameter) and wud put the value for that key in 2nd parameter - value.

__declspec(dllexport) int get_config(LPSTR key, LPSTR val)
{

      if ((idx=searchkey(key))<=Failure)
        ERROR ------
      else
          sprintf(val, "%s", key_arr[idx].ptr);   // ptr is a char*
                  or
          sprintf(val, "%d", *((int*)key_arr[idx].ptr));  // it'll be like this for integers.
}
------------------------------------------------

Also, Form_Load Event has -
---------------------------------------
Dim value As New System.Text.StringBuilder("Hello", 50)
Dim s as String
Dim key as String = "UserID"

get_config(key, value)
s = shortPath.ToString()
---------------------------------------------

This doesn't get me the correct UserID. eg. 101@yahoo.com. It returns as -  "!&llo"
Also i tried  Dim value As New System.Text.StringBuilder(50). This returns NULL.


0
 
LVL 48

Expert Comment

by:AlexFM
ID: 10703277
Define this function as:

public static extern int get_config(IntPtr key, IntPtr val);

key parameter is [in] for get_config function, work with by the way described in my first post.
val parameter is [in, out] for get_config function. Allocate space using Marshal.AllocHGlobal Method (Int32) method and call get_config. To read result written to this buffer by get_config use Marshal.PtrToStringAnsi Method.
0
 
LVL 6

Expert Comment

by:KarunSK
ID: 10705877
Rahul:
As the article by Eric Gunnerson states, using String to get back a value modified in unmanaged memory space will produce undesirable results.

As Alex states, passing a string object and changing it at the DLL will not cause the string to change. I am not sure what is happening at your end.

In your DLLImport statement, declare the second parameter (value as StringBuilder) as UnmanagedType.LPStr. Declaring as LPWStr will cause it to be interpreted as Unicode string, 2 chars wide. But as you know the C strings are 1-byte in width; this will cause a mismatch.

Karun.
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

A basic question.. “What is the Garbage Collector?” The usual answer given back: “Garbage collector is a background thread run by the CLR for freeing up the memory space used by the objects which are no longer used by the program.” I wondered …
This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses

743 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