<body><script type="text/javascript"> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener('load', function(){ object[attribute] = val; }, false); } else { window.attachEvent('onload', function(){ object[attribute] = val; }); } } </script> <div id="navbar-iframe-container"></div> <script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script> <script type="text/javascript"> gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() { if (gapi.iframes && gapi.iframes.getContext) { gapi.iframes.getContext().openChild({ url: 'https://www.blogger.com/navbar.g?targetBlogID\x3d6566853\x26blogName\x3d1%25+inspiration\x26publishMode\x3dPUBLISH_MODE_BLOGSPOT\x26navbarType\x3dBLUE\x26layoutType\x3dCLASSIC\x26searchRoot\x3dhttp://patke.blogspot.com/search\x26blogLocale\x3den\x26v\x3d2\x26homepageUrl\x3dhttp://patke.blogspot.com/\x26vt\x3d8220196945898414734', where: document.getElementById("navbar-iframe-container"), id: "navbar-iframe" }); } }); </script>
Archives
Subscribe


Tuesday, July 20, 2004

Today's technical tidbits:  Passing a sting array to embedded c++ from managed c#.
 
This problem bugged me for a while because pInvoking from a pocket pc machine does not support string arrays, callbacks, or complex objects (except structs - though there is an article today about how this can be achieved.)
 
Anyway, the trick is passing the strings in as an array of IntPtr's.  So, your "pInvoke statements" look like:
 
//cpp.h
TEST_API int TestArrayOfStrings( HANDLE ppStrArray[], int size );
 
//c#.cs
[ DllImport( dllPath)]
public static extern int TestArrayOfStrings( [In, Out] IntPtr[] stringArray, int size );
 
//Function for deallocating string memory - will make more sense in a minute.
const string oleAut32Loc = @"\Windows\oleaut32.dll";
[ DllImport( oleAut32Loc )]
public static extern int SysFreeString( IntPtr ptr);
 
...and once you have that, the hard work is over.  From there, you can pass in string to cpp and read them.  For example:
 
//c#.cs
public void test()
{
   IntPtr[] strArray = new IntPtr[100];
   int lenSum = TEST.TestArrayOfStrings( strArray, 20 );
   MessageBox.Show( "Sum of string lengths:" + lenSum );

   string sb = "";
   foreach( IntPtr s in strArray )
   {
      string val = Marshal.PtrToStringUni(s); 
      TEST.SysFreeString(s);   //destroys memory created in cpp. 
      sb += val + " ";
   }
   MessageBox.Show("String array after call: " + sb );
}
 
//cpp.cpp
TEST_API int TestArrayOfStrings( HANDLE strAry[], int size )

   char* temp;
   for( int i = 0; i < size; i++ ) 
  {
     temp = (char*) CoTaskMemAlloc( sizeof(char) * 40 );
     strcpy( temp, (char*) strAry[ i ] );
     CoTaskMemFree( strAry[ i ] );
     strAry[ i ] = SysAllocString(L"123456789");
  } 
  return size;
}
 
Nifty.

Permalink
Comments: Post a Comment