Thread overview
Calling D DLL from C# and passing/retrieving string variables
Oct 12, 2011
Andre
Oct 12, 2011
Trass3r
Oct 12, 2011
Regan Heath
Oct 12, 2011
casual.james
Oct 13, 2011
Andre
October 12, 2011
Hi,
I try to write a DLL in D which could be called from C#. For testing I want
to write a Concatenate method. The call to the DLL method does not raise
any exception in C# but the out string strResult is empty or it contains
invalid characters.

I tested it with strcopy, toStringz, string.ptr and toUTFz or just passing
a pointer.
Could you give some advice?

D Dll
module mydll;
import std.c.stdio;
import std.c.windows.windows;
import std.c.string;

export extern(C) bool concatenate(
	LPCTSTR str1, LPCTSTR str2, LPTSTR strResult)
{
   strcpy(strResult, "Test");
   return false;
}

C#
namespace DllClient
{
    class Program
    {
        [DllImport("mydll.dll",
            CallingConvention = CallingConvention.Cdecl,
            SetLastError = false, CharSet = CharSet.Auto)]
            private static extern bool concatenate(
                string str1, // in
                string str2, // in
                StringBuilder strResult); // out

        static void Main(string[] args)
        {
            StringBuilder sBuffer = new StringBuilder(4);
            concatenate("abc", "def", sBuffer);
            System.Console.WriteLine("Concatenate Result: " +
sBuffer.ToString());
            System.Console.ReadLine();
        }
    }
}

Kind regards
André
October 12, 2011
>         [DllImport("mydll.dll",
>             CallingConvention = CallingConvention.Cdecl,
>             SetLastError = false, CharSet = CharSet.Auto)]
>             private static extern bool concatenate(
>                 string str1, // in
>                 string str2, // in
>                 StringBuilder strResult); // out

Question is if that StringBuilder really is equal to a char* in this case.
October 12, 2011
On Wed, 12 Oct 2011 17:10:09 +0100, Trass3r <un@known.com> wrote:

>>         [DllImport("mydll.dll",
>>             CallingConvention = CallingConvention.Cdecl,
>>             SetLastError = false, CharSet = CharSet.Auto)]
>>             private static extern bool concatenate(
>>                 string str1, // in
>>                 string str2, // in
>>                 StringBuilder strResult); // out
>
> Question is if that StringBuilder really is equal to a char* in this case.

I believe it can/does work with C DLLs, for example:
http://www.pinvoke.net/default.aspx/kernel32/FormatMessage.html

The first C# FormatMessage signature shown there uses a StringBuilder on the C# side.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
October 12, 2011
On Wed, 12 Oct 2011 18:00:10 +0200, Andre <andre@s-e-a-p.de> wrote:

> Hi,
> I try to write a DLL in D which could be called from C#. For testing I want
> to write a Concatenate method. The call to the DLL method does not raise
> any exception in C# but the out string strResult is empty or it contains
> invalid characters.
>
> I tested it with strcopy, toStringz, string.ptr and toUTFz or just passing
> a pointer.
> Could you give some advice?
>
> D Dll
> module mydll;
> import std.c.stdio;
> import std.c.windows.windows;
> import std.c.string;
>
> export extern(C) bool concatenate(
> 	LPCTSTR str1, LPCTSTR str2, LPTSTR strResult)
> {
>    strcpy(strResult, "Test");
>    return false;
> }
>
> C#
> namespace DllClient
> {
>     class Program
>     {
>         [DllImport("mydll.dll",
>             CallingConvention = CallingConvention.Cdecl,
>             SetLastError = false, CharSet = CharSet.Auto)]
>             private static extern bool concatenate(
>                 string str1, // in
>                 string str2, // in
>                 StringBuilder strResult); // out
>
>         static void Main(string[] args)
>         {
>             StringBuilder sBuffer = new StringBuilder(4);
>             concatenate("abc", "def", sBuffer);
>             System.Console.WriteLine("Concatenate Result: " +
> sBuffer.ToString());
>             System.Console.ReadLine();
>         }
>     }
> }
>
> Kind regards
> André

-            SetLastError = false, CharSet = CharSet.Auto)]
+            SetLastError = false, CharSet = CharSet.Ansi)]

CharSet.Auto will choose UTF-16 unless you add use the Windows ANSI method convention (i.e. name your function "concatenateA"). In D, LPTSTR will use ANSI by default.
October 13, 2011
Am Wed, 12 Oct 2011 21:49:14 +0200 schrieb casual.james@yahoo.es:

> 
> -            SetLastError = false, CharSet = CharSet.Auto)] +            SetLastError = false, CharSet = CharSet.Ansi)]
> 
> CharSet.Auto will choose UTF-16 unless you add use the Windows ANSI method convention (i.e. name your function "concatenateA"). In D, LPTSTR will use ANSI by default.

Thanks a lot. That was the missing part.
Now it is working.

Kind regards
André