Jump to content
  • Advertisement
Sign in to follow this  
Eldritch

Problems with marshaling in .NET Compact Framework (C#)

This topic is 3964 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Here is what I am trying to do: I am trying to get a string from my unmanaged C++ code to my managed C# code. I building my C++ code as a DLL and loading it into my C# app using interop services. C++ Code (.h)
class MyClass
{
public:
    bool getTestString(wchar_t* desc, int& test);
};


C++ Code (.cpp)
bool MyClass::getTestString(wchar_t* desc, int& test)
{
	desc = L"ompa-lompa";
	test = 123;
	return true;
}


C++ Code (.def)
LIBRARY MyModule

EXPORTS
	getTestString			@1


C# Code (.cs)
public sealed class NativeMethods
{
    [DllImport("\\Modules\\MyModule.dll", EntryPoint = "getTestString", CharSet = CharSet.Auto)]
            public static extern bool getTestString(
                                                    [MarshalAs(UnmanagedType.LPWStr)]
                                                    out StringBuilder desc,
                                                    ref int test);
}


This is how I use the above class and method in C#:
StringBuilder desc = new StringBuilder(30);
            int test = 0;
            if (NativeMethods.getTestString(out desc, ref test))
            {
                myLabel = desc;
            }


I get errors when executing the NativeMethods.getTestString(...) line (ExceptionNotSupported). It goes away if I do not use the "out" keyword for the StringBuilder, but still, no text is retrieved from the unmanaged library. How do you retrieve strings from C++ and store them in C# in this manner? I've read lots of documentation on this, but nothing seems to work accordingly... I'm not sure if it's a flaw with the .NET Compact Framework or just something they've missed in the documentation. Please note that the "test" integer variable does get set to 123, so at least integers work, but I need strings (and other stuff later on, like lists and arrays).

Share this post


Link to post
Share on other sites
Advertisement
this function will never return the string.. you just manipulate the local pointer, "desc", but never change anything in the original string.

that's why it works on integers, but not on the string.

it should be something like

bool getTestString(wchar_t** desc, ....)
{
*desc = L"test";
}


or

bool getTestString(wchar_t*& desc, ...)
{
desc = L"test2";
}


to have same behaviour as your integer.

Share this post


Link to post
Share on other sites
Okey, at least I got something back from the C++ function, but it's unreadable. Here are the changes I did in accordance to your suggestions:

(C++)

// Header file:
bool getTestString(WCHAR*& desc, int& test);

// Source file:
bool MyClass::getTestString(WCHAR*& desc, int& test)
{
desc = L"test";
test = 123;
return true;
}



C#

// Importing native function:
[DllImport("\\Modules\\MyModule.dll", EntryPoint = "getTestString", CharSet = CharSet.Auto)]
public static extern bool getTestString(
[MarshalAs(UnmanagedType.LPStr)]
StringBuilder desc,
ref int test);

// Using native function:
StringBuilder desc = new StringBuilder(30);
int test = 0;
if (NativeMethods.getTestString(desc, ref test))
{
label.Text = desc[0];
}



The returned string contains only garbage characters...

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!