views:

1646

answers:

1

Hi,

I have a c++ function with the following signature

TCHAR *DXGetErrorDescription9(HRESULT hr);

I have [DllImport("dxerr9.dll",EntryPoint="GetDXErrorString9")] static public extern string GetDXErrorString9(int DXError);

how do i marshall string to TCHAR*? Thanks

+1  A: 

After doing a little digging, it turns out that the directx error routines are not shipped as dlls, they're shipped as libs that you statically link into your executable. I should have figured this based on the size of dxerr9.lib (it's 5M, way larger than any of the other stub libs).

So to get this to work I did the following:

  1. Make a "wrapper" native dll that wraps all the error handling lib functions. Since there are only 3 (DXGetErrorDescription, DXGetERrorString and DXTrace) this isn't that big a deal.
  2. Have .NET call the wrapper functions.

You can do this in visual studio by creating a Win32 project (change application settings so that it's a dll and so that it exports symbols). I called min "DirectXErrWrapper".

Inside the wrapper project add a passthrough for the DXGetErrorDescription. I called mine DXGetErrDescPassThrough():

extern "C" {

DIRECTXERRWRAPPER_API TCHAR * DXGetErrDescPassThrough(HRESULT hr)
{
    return (TCHAR *)DXGetErrorDescription(hr);
}

}

The extern "C" block is important (has to do with demangling the C++ names). This project will need to #include "dxerr.h" and statically link dxerr.lib so you'll have to add the directx sdk include dir to your include path and the directx sdk lib dir to your lib path.

Then have your managed code import the call from your wrapper dll:

[DllImport("DirectXErrWrapper.dll", CharSet=CharSet.Unicode)]
static public extern string DXGetErrDescPassThrough(int DXError);

In 2005 native projects use unicode by default so the DllImport needed to specify unicode. Lastly, call it from managed code via:

Debug.WriteLine("DXGettErrDescPassThrough=" + DXGetErrDescPassThrough(0));

In this case the call prints "The function completed successfully" to the debug device since 0 is success.

(previous post follows)

That looks like one of the DirectX functions (C++ not C# AFAIK). I'm pretty sure it ships with unicode and ansi versions. TCHAR will map to unicode when compiled on unicode (the T is a mnemonic for type; unicode on unicode, multibyte characterset on mbcs, ansi otherwise). You can usually use CharSet=CharSet.Auto but if that causes compatability problems (e.g., you've gotta use ansi strings because of some struct that you've already ported requires it) you can use whichever is consistent with your project (either Charset.Unicode if you're all unicode or Charset.Ansi) you should have no problem marshaling it into a C# string. You may need to decorate it as [OUT] though the return value may be OUT implicitly. I too wish DirectX shipped w/ TLBs following the standard [out, retval] convention!
Arnshea
Hi, I still can't get it. I've tried numerous conventions. My latest is [DllImport("dxerr9.dll", EntryPoint = "DXGetErrorString9", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] static public extern string DXGetErrorString9(long DXError);Any ideas?
Steve