www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Calling D DLL from C# and passing/retrieving string variables

reply Andre <andre s-e-a-p.de> writes:
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é
Oct 12 2011
next sibling parent Trass3r <un known.com> writes:
         [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.
Oct 12 2011
prev sibling next sibling parent "Regan Heath" <regan netmail.co.nz> writes:
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/
Oct 12 2011
prev sibling parent reply casual.james yahoo.es writes:
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 rai=

 any exception in C# but the out string strResult is empty or it contai=

 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 =3D CallingConvention.Cdecl,
             SetLastError =3D false, CharSet =3D CharSet.Auto)]
             private static extern bool concatenate(
                 string str1, // in
                 string str2, // in
                 StringBuilder strResult); // out

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

 Kind regards
 Andr=E9

- SetLastError =3D false, CharSet =3D CharSet.Auto)] + SetLastError =3D false, CharSet =3D CharSet.Ansi)] CharSet.Auto will choose UTF-16 unless you add use the Windows ANSI meth= od = convention (i.e. name your function "concatenateA"). In D, LPTSTR will u= se = ANSI by default.
Oct 12 2011
parent Andre <andre s-e-a-p.de> writes:
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é
Oct 13 2011