Re: pinvoke with StringBuilder[] not working for me

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



Thanks a lot Ammar. I will try this out.
Is it possible that the array syntax [ ] is looking like a cursor because of
the font you are using?

thanks
LK

"Ammar" <Ammar@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:F86C8AD4-3C86-413D-AA41-27F06B07DF07@xxxxxxxxxxxxxxxx
in this case you need to marshal your array as LPArray so that your
DllImport
would look like this

[DllImport("TestLib.dll")]
public static extern int EnumerateBoards([MarshalAs(UnmanagedType.IntPtr)]
int numBoards, [MarshalAs(UnmanagedType.LPArray)] StringBuilder[] boards);

check this
http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.unmanagedtype(VS.71).aspx

more information on how to pass things between managed and unmanaged code
--
Is that a cursor in your code!


"LK" wrote:

Ammar,

I dont want to pass a char * to my code. If I did, I would have use a
StringBuilder.
I want to pass a pointer to an array of char strings, or char ***. This
translates
to ref StringBuider[]

thanks
LK

"Ammar" <Ammar@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:7A0F167C-4F92-43BB-B36A-C44B0452F4F7@xxxxxxxxxxxxxxxx
i am not sure i understand your code completly but if you want to pass a
pointer to a string this is how you should do it

your export function should be extern "C" __declspec(dllexport) int
EnumerateBoards(int *numBoards, char *boards)

and your importdll should look like this

[DllImport("TestLib.dll")]
public static extern int
EnumerateBoards([MarshalAs(UnmanagedType.IntPtr)]
int numBoards, [MarshalAs(UnmanagedType.LPStr)] StringBuilder boards);

and when you call it from your c#

EnumerateBoards(numBoards, boards);

there is no need to use ref


--
Is that a cursor in your code!


"LK" wrote:

Hi,

From a C# program I need to access an existing DLL that enumerates the
boards detected
via a hardware probe of the system. The function that does the
enumeration
expects an int *
where it stores the number of boards detected and a char *** where it
stores
the name
of each board detected.

Since the String class is immutable, I have used StringBuilder in my
code
but this results in
a NullPointerException. Just for testing I replaced StriingBuilder[]
with
String[] and the code
worked just fine (i.e, no NullPointerExceptions occured and all
messages
populated in
the String[] in managed code was correctly printed by the DLL).

I am wondering what I am doing wrong in my code. For reference, I am
enclosing
my C# code and my sample DLL code

thank you for your help.
Laxmikant Rashinkar (LK)

Here is the C# code
---------------------
using System;
using System.Text;
using System.Runtime.InteropServices;

class CallDll
{
[DllImport("TestLib.dll")]
public static extern void AccessCheck();

[DllImport("TestLib.dll")]
public static extern int EnumerateBoards(ref int numBoards, ref
StringBuilder[] boards);

public static void Main()
{
int numBoards = 0;
int maxBoards = 5;
int i;

StringBuilder[] boards = new StringBuilder[maxBoards];
for(i=0; i<maxBoards; i++)
boards[i] = new StringBuilder(100);

AccessCheck();
EnumerateBoards(ref numBoards, ref boards);
Console.WriteLine("Found " + numBoards + " boards\n");
for(i=0; i<numBoards; i++)
Console.WriteLine("" + boards[i] + "\n");
}
}

Here is the DLL code
----------------------
#include <stdio.h>
#include <string.h>

extern "C" __declspec(dllexport) void AccessCheck()
{
printf("Hello from TestLib.dll\n");
}

extern "C" __declspec(dllexport) int EnumerateBoards(int *numBoards,
char
***boards)
{
char **cpp = *boards;

strcpy(cpp[0], "VGA");
strcpy(cpp[1], "NIC");
*numBoards = 2;
return 0;
}

Here is the output from my program:
------------------------------------
Hello from TestLib.dll

Unhandled Exception: System.NullReferenceException: Object reference
not
set
to
an instance of an object.
at CallDll.EnumerateBoards(Int32& numBoards, StringBuilder[]&
boards)
at CallDll.Main()








.



Relevant Pages

  • Re: pinvoke with StringBuilder[] not working for me
    ... public static extern int EnumerateBoards ... int numBoards, StringBuilder boards); ...
    (microsoft.public.dotnet.framework.interop)
  • Re: Object reference error on EnumChildWindows
    ... int lParam); ... public static extern int EnumWindows ... public static extern void GetWindowText(int h, StringBuilder s, int ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: pinvoke with StringBuilder[] not working for me
    ... I want to pass a pointer to an array of char strings, ... public static extern int EnumerateBoards ... int numBoards, StringBuilder boards); ...
    (microsoft.public.dotnet.framework.interop)
  • Re: problem with P/Involke
    ... public int dwOSVersionInfoSize; ... public static extern int CeCreateFile(string lpFileName, ... public static extern int CeWriteFile(int hFile, StringBuilder ...
    (microsoft.public.dotnet.framework.compactframework)
  • Re: problem with P/Involke
    ... public int dwOSVersionInfoSize; ... public static extern int CeCreateFile(string lpFileName, ... public static extern int CeWriteFile(int hFile, StringBuilder ...
    (microsoft.public.dotnet.framework.compactframework)