Click here to Skip to main content
15,895,667 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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:
C++
// 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:
C++
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:
C#
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:

C++
// 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;

};


C++
// 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
Comments
Sergey Alexandrovich Kryukov 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 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

Hi,

I am sure the following link will help you.I have done such a thing.

http://support.microsoft.com/kb/828736


Cheers
 
Share this answer
 

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900