Hi everybody,
I have some troubles with using my managed C#.Net code in unmanaged C++
code through COM.
I have troubles with passing C# objects to C++ code.
- I have an interface IObjectPass and an object ObjectPass that
implements the interface.
- I have an interface IPassedObject and an object PassedObject that
implements the interface
- I want to assign the object PassedObject via the ObjectPass's
function 'getIPassedObject' parameter.
The code is displayed below.
When I now call the ObjectPass object in C++ through COM and get the
PassedObject, something is not realy going ok. Could somebody give me
some more insight on what happens here. The C++ code is as well
displayed.
Thanks in advance.
Kind regards,
Gerben Heinen
### C# ###
using System;
using System.Runtime.InteropServices;
namespace ClassLibrary1
{
[Guid("71162EC2-6933-43a2-ADB9-03D5B3C53245")]
public interface IObjectPass
{
void getIPassedObject(ref IPassedObject Ipassedobject);
}
[Guid("1767F869-134A-41c0-89EA-5800F7B66B8C")]
public class ObjectPass : IObjectPass
{
public ObjectPass()
{
//
// TODO: Add constructor logic here
//
}
private PassedObject passedobject = new PassedObject();
public void getIPassedObject(ref IPassedObject Ipassedobject)
{
Ipassedobject = passedobject;
}
}
[Guid("A2E71471-6329-4aa2-8F58-469C5F8AD9AD")]
public interface IPassedObject
{
string PassedString
{
get;
set;
}
}
[Guid("2C35ABF6-67A2-4553-BCEC-508117649B34")]
public class PassedObject : IPassedObject
{
public PassedObject()
{
}
private string passedstring = "Ok!";
public string PassedString
{
get { return passedstring; }
set { passedstring = value; }
}
}
}
##########
### C++ ###
// Win32CommCaller.cpp : Defines the entry point for the console
application.
//
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#import <mscorlib.tlb> raw_interfaces_only
#import "ClassLibrary1.tlb" no_namespace named_guids
int _tmain(int argc, _TCHAR* argv[])
{
IObjectPass *op = NULL;
IPassedObject *po = NULL;
char *val = NULL;
_bstr_t *bstrt = NULL;
BSTR *bstr = NULL;
CoInitialize(NULL);
HRESULT hr = CoCreateInstance(CLSID_ObjectPass,
NULL, CLSCTX_INPROC_SERVER,
IID_IObjectPass, reinterpret_cast<void**>(&op));
op->getIPassedObject(&po);
po->get_PassedString(bstr);
printf("Value: %s",bstr);
CoUninitialize();
return 0;
}
###########
Willy Denoyette [MVP] - 24 Sep 2005 19:23 GMT
Check this...
#define _WIN32_WINNT 0x0501
#include <objbase.h>
#include <cstdio>
#import "server.tlb" no_namespace named_guids //raw_interfaces_only
int main(int argc, char *argv[])
{
::CoInitialize(NULL);
HRESULT hr = 0;
_bstr_t str;
IPassedObjectPtr poPtr = 0;
IObjectPassPtr pPtr(__uuidof(ObjectPass));
try
{
hr = pPtr->getIPassedObject(&poPtr);
// using property syntax...
str = poPtr->PassedString;
wprintf_s(L"\n%s\n", static_cast<wchar_t*>(str));
// or using function call syntax
BSTR bstr = str.Detach();
hr = poPtr->get_PassedString(&bstr);
wprintf_s(L"%s\n", bstr);
}
catch (...)
{
printf_s("Hr: %d", hr);
}
::CoUninitialize();
return 0;
}
Willy.
> Hi everybody,
>
[quoted text clipped - 120 lines]
>
> ###########
Egbert Nierop (MVP for IIS) - 24 Sep 2005 23:08 GMT
> Check this...
>
[quoted text clipped - 18 lines]
> // or using function call syntax
> BSTR bstr = str.Detach();
ps: The detach here is a leak imho ...
better use this
BSTR bstr = str;
> hr = poPtr->get_PassedString(&bstr);
> wprintf_s(L"%s\n", bstr);
[quoted text clipped - 4 lines]
> }
> ::CoUninitialize();
Willy Denoyette [MVP] - 25 Sep 2005 11:37 GMT
>> Check this...
>>
[quoted text clipped - 22 lines]
> better use this
> BSTR bstr = str;
Absolutely, I'm leaking the BSTR, my intention was to use GetBSTR() to
explicitely show the OP what should be done to get at the BSTR, but by
mistake I used Detach() - don't know why :-(.
Sure, BSTR bstr = str; will do.
Willy.