How to use namespace System in a managed c++ reference class - c++-cli

I am trying to create managed C++ class by following this tutorial msdn.microsoft.com But while i tried to use namespace System System::String *_msg it always gives me an error that says
An ordinary pointer to a C++/Cli ref class or interface class is not
allowed
Hello.h
using namespace System;
ref class Hello
{
public:
System::String *_msg;
Hello(System::String *Msg);
};
hello.cpp File
#include "Hello.h"
using namespace System;
Hello::Hello(System::String *Msg)
{
Msg = _msg;
Console::WriteLine(Msg);
}
void main() {
Hello ^ h = gcnew Hello("hello world");
}

Instead of unmanaged * pointer use the managed pointer ^ sign:
using namespace System;
ref class Hello
{
public:
System::String ^_msg;
Hello(System::String ^Msg);
};
#include "Hello.h"
using namespace System;
Hello::Hello(System::String ^Msg)
{
Msg = _msg;
Console::WriteLine(Msg);
}
void main() {
Hello ^ h = gcnew Hello("hello world");
}

Related

WinRT C++ component with non primitive function return types fails to compile/build

The below program works fine while having functions with primitive return type functions specifically the Pop function defined below works and I'm able to build properly, but when I build the solution with a function having non primitive return type as in PopC like below project doesn't build, but definitions are syntatically correct and I'm able to see the types being referred properly with proper namespace definitions in pch.h file.
Have defined the below code in the StreamSamplePool.idl file,
namespace WinRTComponent
{
[default_interface]
runtimeclass StreamSamplePool
{
StreamSamplePool();
Int32 MyProperty;
// MediaStreamSample PopC();
Int32 Pop();
}
}
And inside the StreamSamplePool.cpp file have defined the respective methods as follows
#include "pch.h"
#include "StreamSamplePool.h"
#include "StreamSamplePool.g.cpp"
#include <stack>
#include <queue>
using namespace winrt::Windows::Storage::Streams;
using namespace winrt::Windows::Foundation;
using namespace std;
//using namespace Platform;
using namespace winrt::Windows::Media::Core;
namespace winrt::WinRTComponent::implementation
{
int32_t StreamSamplePool::MyProperty()
{
throw hresult_not_implemented();
}
int32_t StreamSamplePool::Pop()
{
return int32_t();
}
//MediaStreamSample StreamSamplePool::PopC()
//{
// MediaStreamSample sample = MediaStreamSample::CreateFromBuffer(NULL,
//TimeSpan());
// //sample.Processed += OnSampleProcessed;
// return sample;
//}
void StreamSamplePool::MyProperty(int32_t /* value */)
{
throw hresult_not_implemented();
}
}
And have defined the following code inside StreamSamplePool.h
namespace winrt::WinRTComponent::implementation
{
struct StreamSamplePool : StreamSamplePoolT<StreamSamplePool>
{
StreamSamplePool() = default;
int32_t Pop();
//MediaStreamSample PopC();
int32_t MyProperty();
void MyProperty(int32_t value);
};
}
namespace winrt::WinRTComponent::factory_implementation
{
struct StreamSamplePool : StreamSamplePoolT<StreamSamplePool,
implementation::StreamSamplePool>
{
};
}
Error info
Error MIDL2011 [msg]unresolved type declaration [context]: WinRTComponent.MediaStreamSample [ Procedure 'PopC' ( RuntimeClass
'WinRTComponent.StreamSamplePool' ) ] WinRTComponent D:\Prithvi\Work\WinRTComponent\StreamSamplePool.idl 9
Compiler output
1>D:\...\StreamSamplePool.idl(9): error MIDL2011: [msg]unresolved type declaration [context]: WinRTComponent.MediaStreamSample [ Procedure 'PopC' ( RuntimeClass 'WinRTComponent.StreamSamplePool' ) ]
1>Done building project "WinRTComponent.vcxproj" -- FAILED.
The issue can be reduced to the following IDL file:
namespace WinRTComponent
{
[default_interface]
runtimeclass StreamSamplePool
{
StreamSamplePool();
MediaStreamSample PopC();
}
}
Compiling this using a default-generated C++/WinRT Component project produces the following error:
1>C:\...\StreamSamplePool.idl(7): error MIDL2011: [msg]unresolved type declaration [context]: WinRTComponent.MediaStreamSample [ Procedure 'PopC' ( RuntimeClass 'WinRTComponent.StreamSamplePool' ) ]
It contains all the information required to resolve the issue. In particular it's naming the error ("unresolved type declaration"), and the procedure affected ("PopC"). To solve this you'll have to provide the fully-qualified type name in the IDL file, i.e.
namespace WinRTComponent
{
[default_interface]
runtimeclass StreamSamplePool
{
StreamSamplePool();
Windows.Media.Core.MediaStreamSample PopC();
}
}
With that done, go to the "Generated Files\sources" directory under the project root, and copy the respective parts of the "StreamSamplePool.h" and "StreamSamplePool.cpp" files that the build system generated to your source files.

Call c++ code in c# by a cli wrapper

I have a c++ code that needs to be called in c# by a cli wrapper. I am stuck at the operator overloading part.
//this is my code
//Cppclass.h
#ifdef CPP_EXP_EXPORTS
#define CPP_EXP __declspec(dllexport)
#else
#define CPP_EXP __declspec(dllimport)
#endif
class CPP_EXP Cppclass;
CPP_EXP Cppclass operator-(Cppclass const &, Cppclass const &);
class CPP_EXP Cppclass
{
public:
friend CPP_EXP Cppclass operator-(Cppclass const &, Cppclass const &);
};
//this is my managed c++ code.
#include "Cppclass.h"
namespace Wrapper
{
public ref class cppwrapclass
{
public:
static cppwrapclass ^ operator-(cppwrapclass%A,cppwrapclass%B)
{
operator-(A.obj,B.obj);
return gcnew cppwrapclass();
}
private:
Cppclass *obj;
};
}
Its showing an intellisense error and not getting compiled.
You write a wrapper like this:
public ref class cppwrapclass
{
public:
cppwrapclass(Cppclass *obj)
: obj(obj)
{
}
~cppwrapclass()
{
this->!cppwrapclass();
}
!cppwrapclass()
{
if (obj)
{
delete obj;
obj = nullptr;
}
}
static cppwrapclass^ operator-(cppwrapclass% A, cppwrapclass% B)
{
return gcnew cppwrapclass(new Cppclass(*A.obj - *B.obj));
}
private:
Cppclass* obj;
};
A.obj is of type Cppclass*, therefore *A.obj is of type Cppclass, and *A.obj - *B.obj is a temporary Cppclass which needs to be moved to the heap in order to be referenced by the wrapper, hence the copy constructor call: new Cppclass(*A.obj - *B.obj).
The rest is the Dispose pattern and finalizer plumbing code.

Convert C++/CLI User Defined Object (%) to Native C++ object (&)

How can I convert a user defined object passed by (%) to a native object (&). For example
void managed_func(user_defined_managed_obj% m_obj_)
{
// i need this
obj_ptr->unmanaged_func(&m_obj_);
}
Thus, in the above example I would like to pass the managed object %m_obj_ to the argument of the unmanaged_func. Here user_defined_managed_obj is a .net wrapper in C++/CLI that is a bridge for a native C++.
I've tried the following:
pin_ptr<user_defined_unmanaged_obj> tmp_ptr = &m_obj_;
obj_ptr->unmanaged_func(*tmp_ptr);
Will someone point me into the right direction or let me know what I can do to remedy this problem. Thank you.
Edit:
The user_defined_unmanaged_obj is a native C++ object and the user_defined_managed_obj is the wrapper C++/CLI class for it.
Edit:
The following are the code
In native C++, native_sql.h
#include <string>
class native_sql
{
public:
native_sql(string arguments)
{...some codes}
~native_sql(void) = default;
void connect(void) {...some codes}
void clean(void) {...some codes}
}
In native C++, native_upload_specific_data.h
#include "native_sql.h"
#include <string>
class native_upload_specific_data
{
public:
native_upload_specific_data(string arugments) {...some codes}
~native_upload_specific_data(void)
void upload(native_sql& sql_obj_) {...some codes}
}
In C++/CLI, sql_wrapper.h
#include <msclr\marshal_cppstd.h>
#include "../native_sql.h"
#include "../native_sql.cpp"
using namespace System;
public ref class sql_wrapper
{
public:
sql_wrapper(String^ arguments)
{...codes to convert String^ to std::string and pass args to
new native_sql}
~sql_wrapper(void) { delete sql_ptr; }
void connect_wrapper(void) { sql_ptr->connect(); }
void clean_wrapper(void) { sql_ptr->clean(); }
native_sql* sql_ptr;
}
In C++/CLI wrapper, upload_specific_data_wrapper.h
#include "../native_upload_specific_data.h"
#include "../native_upload_specific_data.cpp"
using namespace System;
public ref class upload_specific_data_wrapper
{
public:
upload_specific_data_wrapper(String^ arguments)
{...convert String^ args into std::strings and pass to
native_upload_specific_data ctor}
~upload_specific_data_wrapper(void) { delete data_ptr; }
void upload(sql_wrapper% sql_obj_)
{
// here is where I have the problem
pin_ptr<native_sql*> ptr = &(sql_obj_.sql_ptr);
data_ptr->upload(ptr);
}
native_upload_specific_data* data_ptr;
}
The error I receive is
C2664: 'void native_upload_specific_data(native_sql&)': cannot convert arugment 1 from cli::pin_ptr<native_sql*> to native_sql&
....Thank you.

C++ CLI Wrapper

I’ve a question about creating a C++ CLI Wrapper for a native C++ class to be used in C#.
Here is an example code:
#include "stdafx.h"
#pragma once
using namespace System;
namespace Wrapper {
class NativeClass
{
public:
NativeClass() {}
int Add(int a, int b)
{
return a+b;
}
};
public ref class Wrapper
{
public:
Wrapper() {pNative = new NativeClass();}
int Add(int a, int b)
{
return(pNative->Add(a,b));
}
~Wrapper()
{
delete pNative;
pNative = 0;
}
!Wrapper()
{
this->~Wrapper();
}
//My problem is here.
NativeClass* GetNative()
{
return pNative;
}
private:
NativeClass* pNative;
};
}
This code works fine. I need to retrieve the pointer that refers the native class to use it in the other wrapper classes. However, I don’t want the function “GetNative” to be visible in C# when I’m using this wrapper class. How can I hide it?
If the other wrapper classes are in the same assembly, make the access internal instead of public. – Roger Rowland Apr 25 '13 at 9:47
.
if they are not in the same assembly? ...
Look into friend assemblies – Sebastian Cabot Feb 1 at 15:43

Mono CSharp Evaluator : creating two Action<object> via two distinct Run() crashes

I'm trying to embed mono in a c++ executable, and mono crashes on the second evaluator.Run(..) as below. Any idea of what I missed ?
Using mono 3.0.3.
EmbeddedMonoTest.cpp
// EmbeddedMonoTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/exception.h>
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
int _tmain(int argc, _TCHAR* argv[])
{
MonoDomain* domain = mono_jit_init_version ("ClassLibrary1", "v4.0.30319");
MonoAssembly* assembly = mono_domain_assembly_open (domain, "ClassLibrary1.dll");
mono_assembly_get_image(mono_domain_assembly_open (domain, "Mono.CSharp.dll"));
MonoImage* image = mono_assembly_get_image (assembly);
MonoClass* klass = mono_class_from_name(image, "ClassLibrary1", "Class1");
MonoMethod* test = mono_class_get_method_from_name(klass, "Test", 0);
mono_runtime_invoke(test, NULL, NULL, NULL);
return 0;
}
Class1.cs
using System;
using System.Reflection;
using Mono.CSharp;
namespace ClassLibrary1
{
public class Class1
{
public static void Test()
{
var assembly = Assembly.GetAssembly(typeof(Class1));
CompilerSettings settings = new CompilerSettings();
ReportPrinter printer = new ConsoleReportPrinter();
CompilerContext context = new CompilerContext(settings, printer);
Evaluator evaluator = new Evaluator(context);
evaluator.ReferenceAssembly(assembly);
evaluator.Run("using System; using ClassLibrary1;");
evaluator.Run("Action<object> action = args => {{ 'x'.ToString(); }}; ");
evaluator.Run("Action<object> b = args => {{ 'x'.ToString(); }}; ");
}
}
}
The error :
Unhandled exception at 0x0274b00d in EmbeddedMonoTest.exe: 0xC0000005: Access violation reading location 0x00000000.