Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ C++/CLI C#
Hey experts, i'm trying to achieve the following:
i have an already written c++ class (which i can't touch), it looks like this:
 
// this is the class i want to pass.
class CCPlus
{
public:
	CCPlus();
	~CCPlus();
	void WriteToLog(char* toWrite);
	void setNumber(int num);
	void printNumber();
	int  getNumber();
	void setInternalString(char* str);
	void printInternalString();
 

private:
	int m_Number;
	CSTRHolder* m_holder;
};
 
//and the STRHolder:
class CSTRHolder
{
public:
	CSTRHolder(void);
	~CSTRHolder(void);
	void setString(char* str);
	char* getCopyOfString();
private:
	char* m_str;
};
 
Then i want to create a c++ project that does something like that:
void main()
{
  CCPlus* p = new CCPlus();
  p->setNumber(10);
 
  // now I want to call a C# dll, and pass the "p" pointer.
  // something like:
  int result =  MyManagedClass::DoOperation(&p);
  // where MyManagedClass is below:
}
 
lets say i have in C# something like this:
namespace ManagedDotnet
{
    public class MyManagedClass
    {
        public static int DoOperation(CCPlusWrapper p)
        {
             Console.Writeline(p.getNumber());
             p.setInternalString("Hello");
             p.printInternalString();
             return 0;
        }
    }
}
 

i've created a project in c++/CLI that suppose to wrap the unmanaged class:
 
// MyBridge.h

#pragma once
 
using namespace System;
 

class CCPlus;
 
public ref class Bridger
{
public:
	Bridger(CCPlus* myUnmanaged);
	~Bridger();
	void WriteToLog(String^ toWrite);
	void setNumber(int num);
	void printNumber();
	int  getNumber();
	void setInternalString(String^ str);
	void printInternalString();
private:
	CCPlus* m_pUnmanaged;
 
};
 
// This is the main DLL file.

#include "stdafx.h"
#include "MyBridge.h"
#include <stdio.h>
#include "CPlus.h"
#include <vcclr.h>
#include <iostream>

using namespace std;
using namespace System;
Bridger::Bridger(CCPlus* myUnmanaged)
:m_pUnmanaged(NULL)
{	
	this->m_pUnmanaged = myUnmanaged;	
}
Bridger::~Bridger()
{
 
}
void Bridger::WriteToLog(String^ toWrite)
{	
   // Pin so GC won't move the managed string around
   pin_ptr<const wchar_t> ptr = PtrToStringChars(toWrite);
   m_pUnmanaged->WriteToLog((char*)static_cast<const wchar_t*>( ptr ));   
}
void Bridger::setNumber(int num)
{
	m_pUnmanaged->setNumber(num);
}
void Bridger::printNumber()
{	
	m_pUnmanaged->printNumber();
}
int  Bridger::getNumber()
{
	return m_pUnmanaged->getNumber();
}
void Bridger::setInternalString(String^ str)
{
   pin_ptr<const wchar_t> ptr = PtrToStringChars(str);
   m_pUnmanaged->setInternalString((char*)static_cast<const wchar_t*>( ptr ));   
}
void Bridger::printInternalString()
{
	m_pUnmanaged->printInternalString();
}
 

But now, i need to somehow create this wrapper in C++, pass the unmanaged object, then call another C# DLL, and pass that wrapper to there?
 
or my direction is wrong?
i'm trying to avoid COM by the way.
 
thanks!
Posted 25-Dec-11 6:03am
arielb558
Comments
SAKryukov at 25-Dec-11 13:10pm
   
Your approach looks suspicious to me, but to help you, I need to know why. Will you share your ultimate goals?
 
To start with, I can tell you: let's forget COM, avoid it by all means.
I can tell you in advance just one thing: exporting managed methods as unmanaged is also possible, but more difficult compared with P/Invoke. There is a method, but it involves manipulations with ILASM/ILDASM (which can be automated in build steps). So, I first would consider avoiding it, too.
 
Also, can you consider using C++/CLI? Can your code which you say "I cannot touch" be moved to C++/CLI project, which is of course quite possible?
 
Generally, what's the idea behind using managed and unmanaged in a solution. What are the requirements and why?
 
You see, I simply don't want to give you any suggestions based merely on your "I want". The solutions might look pretty difficult, but not effective because the whole idea can be questionable.
 
--SA
arielb at 26-Dec-11 13:50pm
   
Hey, first of all, thanks for the comment! i will explain fully:
 
We have an engine, which is c++ written.
Somewhere along the execution, we call a user exit (which can be written in C++, perl, and batch).
i want to add implementation for .NET user exit - which means, the end user will write his user exit with C# (important to mention, that there's always a parameter when the user exit starts, an object that can be manipulated by the user. (like obj->SetInternalFlag(), or obj->WriteToLog(...))
 
so thats why, i need my c++ to call a user written C# DLL, and pass the c++ object where the user, inside C#, can call methods on,
then after the DLL is called (and i need a return code from his DLL - means, he should write a function that returns bool), i need to continue execution.
 
General user exit method looks like that, for example:
bool DoUserExitPostOperation(PostOperationObject obj);
 
For your second part,
i did consider to use c++/CLI (thats what i posted in my question), I can touch the engine, but at some point i need to call that C# dll, which is problematic to me.
anxiously waiting for your answer :)

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Hi,
 
I am sure the following link will help you.I have done such a thing.
 
http://support.microsoft.com/kb/828736
 

Cheers
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 Richard MacCutchan 269
1 Aajmot Sk 252
2 Marcin Kozub 235
3 Sergey Alexandrovich Kryukov 185
4 Praneet Nadkar 167
0 OriginalGriff 7,913
1 Sergey Alexandrovich Kryukov 7,232
2 DamithSL 5,604
3 Manas Bhardwaj 4,986
4 Maciej Los 4,865


Advertise | Privacy | Mobile
Web02 | 2.8.1411023.1 | Last Updated 3 Jan 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100