[Out] param in C++ called from C#

G

Guest

I have a managed C++ DLL that contains the following:

MyLib.h:
// MyLib.h
#pragma once
using namespace System;
using namespace System::Runtime::InteropServices;
namespace MyLib
{
public __gc class MyClass
{
public:
Boolean MyMethod([Out] String *cParam);
};
}

MyLib.cpp
// This is the main DLL file.
#include "stdafx.h"
#include "MyLib.h"
namespace MyLib
{
Boolean MyClass::MyMethod([Out] String *cParam)
{
cParam = S"My String!";
return true;
}
}

I've added the resulting DLL as a reference to my C# console app and I can't
get the C# app to compile.
MyApp.cs:
using System;
using MyLib;
namespace MyApp
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
MyClass o = new MyClass();
string oStr;
o.MyMethod(out oStr);
Console.WriteLine(oStr);
}
}
}

I’m getting the following errors when compiling MyApp.cs:
--> D:\DlgProc\MyApp\Class1.cs(20): The best overloaded method match for
'MyLib.MyClass.MyMethod(string)' has some invalid arguments
--> D:\DlgProc\MyApp\Class1.cs(20): Argument '1': cannot convert from 'out
string' to 'string'

What am I doing wrong?
thanks
 
V

Vladimir Nesterovsky

I have a managed C++ DLL that contains the following:
MyLib.h:
// MyLib.h
#pragma once
using namespace System;
using namespace System::Runtime::InteropServices;
namespace MyLib
{
public __gc class MyClass
{
public:
Boolean MyMethod([Out] String *cParam);
};
}

I believe there should be something like:
Boolean MyMethod([Out] String * &cParam);
 
G

Guest

Great! But what if I my parameter is an array. The compiler won't let me do
this:
Boolean MyMethod([Out] String * &cParam[]);

Vladimir Nesterovsky said:
I have a managed C++ DLL that contains the following:

MyLib.h:
// MyLib.h
#pragma once
using namespace System;
using namespace System::Runtime::InteropServices;
namespace MyLib
{
public __gc class MyClass
{
public:
Boolean MyMethod([Out] String *cParam);
};
}

I believe there should be something like:
Boolean MyMethod([Out] String * &cParam);
 
G

Guest

Whoa! I figured it out. I couldn’t find this anywhere and had to resort to
trial and error. In case anyone else is interested, here it is:
// MyLib.h
#pragma once
using namespace System;
using namespace System::Runtime::InteropServices;
namespace MyLib
{
public __gc class MyClass
{
public:
Boolean MyMethod([Out] String __gc* (&cParam) __gc[]);
};
}

// MyLib.cpp
#include "stdafx.h"
#include "MyLib.h"
namespace MyLib
{
Boolean MyClass::MyMethod([Out] String __gc* (&cParam) __gc[])
{
cParam = __gc new String*[5];
cParam[0] = S"Item 1";
cParam[1] = S"Item 2";
cParam[2] = S"Item 3";
cParam[3] = S"Item 4";
cParam[4] = S"Item 5";
return true;
}
}

// MyLib.cs
using System;
using MyLib;
namespace MyApp
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
MyClass o = new MyClass();
string[] oStr = null;
o.MyMethod(out oStr);
foreach (string s in oStr)
{
Console.WriteLine(s);
}
}
}
}


dlgproc said:
Great! But what if I my parameter is an array. The compiler won't let me do
this:
Boolean MyMethod([Out] String * &cParam[]);

Vladimir Nesterovsky said:
I have a managed C++ DLL that contains the following:

MyLib.h:
// MyLib.h
#pragma once
using namespace System;
using namespace System::Runtime::InteropServices;
namespace MyLib
{
public __gc class MyClass
{
public:
Boolean MyMethod([Out] String *cParam);
};
}

I believe there should be something like:
Boolean MyMethod([Out] String * &cParam);
 
W

Willy Denoyette [MVP]

Change it to :

Boolean MyMethod([Out] String __gc* (*cParam) __gc[]);

to make it CLS compliant.

Willy.


dlgproc said:
Whoa! I figured it out. I couldn't find this anywhere and had to resort to
trial and error. In case anyone else is interested, here it is:
// MyLib.h
#pragma once
using namespace System;
using namespace System::Runtime::InteropServices;
namespace MyLib
{
public __gc class MyClass
{
public:
Boolean MyMethod([Out] String __gc* (&cParam) __gc[]);
};
}

// MyLib.cpp
#include "stdafx.h"
#include "MyLib.h"
namespace MyLib
{
Boolean MyClass::MyMethod([Out] String __gc* (&cParam) __gc[])
{
cParam = __gc new String*[5];
cParam[0] = S"Item 1";
cParam[1] = S"Item 2";
cParam[2] = S"Item 3";
cParam[3] = S"Item 4";
cParam[4] = S"Item 5";
return true;
}
}

// MyLib.cs
using System;
using MyLib;
namespace MyApp
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
MyClass o = new MyClass();
string[] oStr = null;
o.MyMethod(out oStr);
foreach (string s in oStr)
{
Console.WriteLine(s);
}
}
}
}


dlgproc said:
Great! But what if I my parameter is an array. The compiler won't let me
do
this:
Boolean MyMethod([Out] String * &cParam[]);

Vladimir Nesterovsky said:
I have a managed C++ DLL that contains the following:

MyLib.h:
// MyLib.h
#pragma once
using namespace System;
using namespace System::Runtime::InteropServices;
namespace MyLib
{
public __gc class MyClass
{
public:
Boolean MyMethod([Out] String *cParam);
};
}

I believe there should be something like:
Boolean MyMethod([Out] String * &cParam);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top