Question

I need to create a C++ dll that will be called from another program through stdcall.

What is needed : the caller program will pass an array of string to the dll and the dll should change the string values in the array. The caller program will then continue to work with these string values that came from the dll.

I made a simple test project and I am obviously missing something...

Here is my test C++ dll :

#ifndef _DLL_H_
#define _DLL_H_

#include <string>
#include <iostream>

struct strStruct
{
    int len;
    char* string;
};

__declspec (dllexport) int __stdcall TestFunction(strStruct* s)
{
   std::cout << "Just got in dll" << std::endl;

   std::cout << s[0].string << std::endl;
   //////std::cout << s[1].string << std::endl;

   /*
   char str1[] = "foo";
   strcpy(s[0].string, str1);
   s[0].len = 3;

   char str2[] = "foobar";
   strcpy(s[1].string, str2);
   s[1].len = 6;
   */

   //std::cout << s[0].string << std::endl;
   //std::cout << s[1].string << std::endl;

   std::cout << "Getting out of dll" << std::endl;

   return 1;
}

#endif

and here is a simple C# program that I am using to test my test dll :

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Runtime.InteropServices;

 namespace TestStr
 {
     class Program
     {
         [DllImport("TestStrLib.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
         public static extern int TestFunction(string[] s);

         static void Main(string[] args)
         {
             string[] test = new string[2] { "a1a1a1a1a1", "b2b2b2b2b2" };

             Console.WriteLine(test[0]);
             Console.WriteLine(test[1]);

             TestFunction(test);

             Console.WriteLine(test[0]);
             Console.WriteLine(test[1]);

             Console.ReadLine();
         }
     }
 }

And here is the output produced :

a1a1a1a1a1
b2b2b2b2b2
Just got in dll
b2b2b2b2b2
Getting out of dll
a1a1a1a1a1
b2b2b2b2b2

I have some questions :

1) Why is it outputting the element in the second position of the array rather than in the first position??

2) If I uncomment the line commented with ////// in the dll file, the program crashes. Why?

3) Obviously I wanted to do more things in the dll (the parts in /* */) than what it does right now, but I am blocked by the first 2 questions...

Thanks for all your help

Was it helpful?

Solution

You cannot marshal a string[] as a native struct

    [DllImport("TestStrLib.dll", CharSet = CharSet.Ansi, 
             CallingConvention = CallingConvention.StdCall)]
             public static extern int TestFunction(string[] s);

      struct strStruct
        {
            int len;
            char* string;
        }

    __declspec (dllexport) int __stdcall TestFunction(strStruct* s);

Please read http://msdn.microsoft.com/en-us/library/fzhhdwae.aspx for marshalling of various types.

In C#

    [DllImport( "TestStrLib.dll" )]
    public static extern int TestFunction([In, Out] string[] stringArray
    , int size);

In C++

__declspec(dllexport) int TestFunction( char* ppStrArray[], int size)
   {
       return 0;
   }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top