Click to See Complete Forum and Search --> : passing string type to C++


Saeed
August 25th, 2008, 10:58 PM
How do you pass on a simple string or byte array ....type to C# and get it back from C# in C++ ?

I have managed to do it with integer but with ANSI strings does not seem so simple.

ashukasama
August 26th, 2008, 12:54 AM
from C# to c++

http://bytes.com/forum/thread250052.html

Saeed
August 26th, 2008, 01:52 AM
'Get' : cannot convert parameter 1 from 'char *' to 'struct tagSAFEARRAY *'

#include "stdafx.h"
#include "tchar.h"
#include <comutil.h>

#include <string>
// Import the type library.

//#import "..\ManagedDLL\bin\Debug\ManagedDLL.tlb" raw_interfaces_only
#import "C:\Mydot-net-projects\sManagedDLL\sManagedDLL\bin\Debug\sManagedDLL.tlb"
using namespace sManagedDLL;
int _tmain(int argc, _TCHAR* argv[])
{
// Initialize COM.
HRESULT hr = CoInitialize(NULL);

// Create the interface pointer.
ICalculatorPtr pICalc(__uuidof(ManagedClass));

long lResult = 0;
std::string str;

// Call the Add method.
// pICalc->Add(5, 10, &lResult);
wprintf(L"The result1 is [%d]\n", pICalc->Add(5, 10));
char p[10];


char *szTemp = new char [1000];
strcpy(szTemp,"Test");
wprintf(L"The result2 is p=[%s]\n",pICalc->Get(szTemp) );


// Uninitialize COM.
CoUninitialize();
return 0;
}



and in C#

using System;
using System.Collections.Generic;
using System.Text;

namespace sManagedDLL
{

// Interface declaration.
public interface ICalculator
{
int Add(int Number1, int Number2);
string Get(char [] s);
};
// Interface implementation.
public class ManagedClass : ICalculator
{
public int Add(int Number1, int Number2)
{
return Number1 + Number2+3;
}
public string Get(char[] s)
{
StringBuilder sBuffer = new StringBuilder(100);
return sBuffer.ToString();

}
}
}

darwen
August 26th, 2008, 03:03 PM
You pass strings in and out in C++ by using BSTRs - these are the COM standard strings.

See AllocSysString and FreeSysString in the C++ Win32 API.

Or _bstr_t (ATL) or CComBSTR (MFC) which are wrapper classes for BSTRs.

On the C# side of things you should do :


public string Get(IntPtr s)
{
return System.Runtime.InteropServices.Marshal.PtrToStringAnsi(s);
}


char[] will be translated to a safearray of chars by default.

The return type in C++ since you're using #import will be a _bstr_t so you can't just pipe it into a printf : you need to convert it to a char * first e.g.


wprintf(L"The result2 is p=[%s]\n",static_cast<wchar_t *>(pICalc->Get(szTemp)) );


Or you can try

using System.Runtime.InteropServices;

string Get([MarshalAs(UnmanagedType.LPStr)] string input)
{
return input;
}


which should work for char * arrays being passed from C++ but I've not tried it.

You should also assign [Guid] attributes to both your interface and your class otherwise everytime you re-register them they'll get a different COM Guid and cause all sorts of problems.

They should both also have the [ComVisible(true)] attribute to make sure they're exportable to COM.

Darwen.

Saeed
August 26th, 2008, 06:28 PM
Darwen;

You are A++ genius mate .
Thanks :thumb: