Sign in to follow this  
thezbuffer

Calling d3d directly from managed code

Recommended Posts

After finding out that Font.MeasureString suffered from a missing feature I thought "hey I've been looking for an excuse to try to call into the native code directly". Many hours of MSDN and google later I give up realising my knowledge of COM, type libraries and C++ is useless if Visual Studio doesn't handle all the magic plumbing for me. However now I've blown hours I could have been doing something useful I still feel the need to know where I'm missing the point or just how far away I was from the solution (or maybe there is no solution!). I need a way to call ID3DXFont.Draw() from C# directly. 1. Write a managed wrapper just like MDX in C++/CLI 2. Call D3DX_dll directly I went with #2 thinking that since I only needed one call it would be similar to doing a PInvoke and heck I've called COM objects from .Net lots of times. Problem: No type library for d3dx, no idl file either. tlbimp won't create one for me saying that the dll is not a valid type library and of course I don't have a type library. I found some examples of creating an interface in .Net by hand but those examples show how to convert IDL which I don't have. the d3dxcore.h file has something that looks a bit like the IDL file fo ID3DXFont so maybe I can convert that. Then I can get the unmanaged Com Pointer and cast it to that interface in an unsafe block and I would be off - right? I figured I was now guessing so much that the odds of it working were negligible. So C++ and COM gurus I throw myself on your expertise to hopefully learn something useful. Is it even possible to call it from within C# (unsafe is fine)

Share this post


Link to post
Share on other sites
The reason why there is no type library for D3DX is that DX use only the IUknown part of COM. Anything else is based on custom interfaces. It is possible to create managed interfaces for custom COM interface with C# but it has the tendency to gives you very ugly code.

I don’t have the right wrapper for your interface here but it have to look like this:

[ComVisible(true), ComImport,
Guid("F31DFDE2-07B6-11d2-B2D8-0060083BA1FB"), <- replace with the right one
InterfaceType( ComInterfaceType.InterfaceIsIUnknown )]
internal interface ITest
{
[Add all methods of the interface in the right order but not the IUnknown part]
}


The methods are marshaled in the same way as normal functions with P/Invoke.

Share this post


Link to post
Share on other sites
I'm a better guesser than I thought, thats pretty much the code I had typed in before I gave up in disgust at 1am last night.

I'm going to go and guess some lottery numbers now :-)

Oh and thanks for the information.

[Edited by - thezbuffer on May 18, 2006 11:28:16 AM]

Share this post


Link to post
Share on other sites
make an idl file for the interface you want.
format is as follows:

import "C:\Program Files\Microsoft Platform SDK\Include\prsht.idl";
import "C:\Program Files\Microsoft Platform SDK\Include\mshtml.idl";
import "c:\program files\microsoft platform sdk\include\dimm.idl";
import "C:\Program Files\Microsoft Platform SDK\Include\mshtmhst.idl";
import "c:\program files\microsoft platform sdk\include\docobj.idl";
import "C:\Program Files\Microsoft Platform SDK\Include\exdisp.idl";
import "C:\Program Files\Microsoft Platform SDK\Include\objsafe.idl";

[
local,
uuid(D0223B96-BF7A-43fd-92BD-A43B0D82B9EB)
]
interface IDirect3DDevice9 : IUnknown
{
};

uuid should be the interface uuid in your system.
interface name should be the interface name you want.

I transfered IDirect3DDevice9 among interface funtions with the above idl file successfully for our project. you can try my method.

Share this post


Link to post
Share on other sites
But since there is no DirectX IDL I have to translate the .h files back into IDL, which is the same thing as translating them into c# interfaces. SO either way I have to do the work by hand? Or an I missing some obvious point - is there a quick way to go from the intrface defn in the .h file to a .idl

(feel free to assume I know nothing here - its not far from the truth)

Share this post


Link to post
Share on other sites
I don't know C#. But my idl works fine for my vc++ directx project.

put the following statement in the header file where you need the device definition, it's done. MIDL.exe will recognize the interface automatically.


[importidl("d3d9.idl")];

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this