Jump to content
  • Advertisement
Sign in to follow this  
obi-wan shinobi

[.net] c++.net & directx9 issue

This topic is 4831 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

The code below is intended to create a Windows Form and initialize Direct3D for it based on Tutorial #1 of the DXSDK. I'm trying to do this in managed c++.net because I've seen how it is done in c# and know how to do it in standard c++, however, I have a problem that is somewhat unclear to me. What does it mean by "imported native types must be defined in the importing source code"? Do I have to include the unmanaged DX9 headers and libraries? Use a pragma or another using directive? Using the vc++ toolkit 2003 command prompt, this is my command: c:\>cl /clr mdx9.cpp ...and these are my errors... mdx9.cpp(53) : error C3635: 'Microsoft.DirectX.PrivateImplementationDetails::IDirect3DDevice9': undefined native type used in 'Microsoft::DirectX::Direct3D::Device'; imported native types must be defined in the importing source code did you forget to include a header file? mdx9.cpp(53) : error C3377: 'Microsoft::DirectX::Direct3D::Device::.ctor' : cannot import method - a parameter type or the return type is inaccessible mdx9.cpp(53) : error C3635: 'Microsoft.DirectX.PrivateImplementationDetails::IDirect3DDevice9': undefined native type used in 'Microsoft::DirectX::Direct3D::Device'; imported native types must be defined in the importing source code did you forget to include a header file? mdx9.cpp(53) : error C3377: 'Microsoft::DirectX::Direct3D::Device::get_UnmanagedComPointer' : cannot import method - a parameter type or the return type is inaccessible mdx9.cpp(53) : error C3635: 'Microsoft.DirectX.PrivateImplementationDetails::IDirect3DDevice9': undefined native type used in 'Microsoft::DirectX::Direct3D::Device'; imported native types must be defined in the importing source code did you forget to include a header file? mdx9.cpp(53) : error C3377: 'Microsoft::DirectX::Direct3D::Device::UpdateUnmanagedPointer' : cannot import method - a parameter type or the return type is inaccessible
#using <mscorlib.dll>
#using <System.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
#using "c:\managedDX9dll\Microsoft.DirectX.dll"
#using "c:\managedDX9dll\Microsoft.DirectX.Direct3D.dll"
using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;
using namespace Microsoft::DirectX;
using namespace Microsoft::DirectX::Direct3D;


__gc class makedevice {

	private:
	Device			*dev;
	PresentParameters	*pp;
	Form			*form;
	
	public:
	makedevice() {
		form = new Form();
		dev = null;
		form->Size =  new Size(800,600);
		form->Text = "Managed Direct3D in C++.net";
	}
	
	bool initgfx() {
		try{
			pp = new PresentParameters();
			pp->Windowed = true;
			pp->SwapEffect = SwapEffect->Discard;
			dev = new Device(0, DeviceType->Hardware,
			this, CreateFlags->SoftwareVertexProcessing,pp);
			return true;
		}
		catch(DirectXException *dxe) {
			return false;
		}
	}

	void render() {
		if(dev == null) {
			MessageBox->Show("Device is null...");
			return;
		}
		dev->Clear(ClearFlags->Target, Color->Blue, 1.0f, 0);
		dev->BeginScene();
		dev->EndScene();
		dev->Present();
	}
};

int main() {
	makedevice *md = new makedevice();
	bool start = md->initgfx();
	if(start == false) {
		return 0;
	}
	while(start == true) {
		md->render();
	}
	return 0;
}

Share this post


Link to post
Share on other sites
Advertisement
Oof, that's lame. It's complaining that you need to #include some headers... but the managed assemblies don't have headers (they have metadata embedded in the assembly).

Instead of using "#using <managed-dll.DLL>", see if you can get it to work if you use the "References" stuff in Visual Studio's IDE (there's some way to specify the references assemblies on the command line, but I don't remember it).

Share this post


Link to post
Share on other sites
Strangely enough, those errors in the opening post disappear when I use the VC++.net beta's command prompt. Now I can almost get it to work if it weren't for one problem with the PresentParameters object...apparently in c#, the PresentParameters object is automatically given an array, however in c++.net, this is not the case as the following error apparently replaces the others:

mdx9.cpp(28) : error C2664: 'Microsoft::DirectX::Direct3D::Device::Device(int,Mi
crosoft::DirectX::Direct3D::DeviceType,System::IntPtr,Microsoft::DirectX::Direct
3D::CreateFlags,Microsoft::DirectX::Direct3D::PresentParameters __gc * __gc[])'
: cannot convert parameter 5 from 'Microsoft::DirectX::Direct3D::PresentParamete
rs __gc *' to 'Microsoft::DirectX::Direct3D::PresentParameters __gc * __gc[]'

Here's the touched-up c++ code:

#using <mscorlib.dll>
#using <System.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
#using <c:\managedDX9dll\Microsoft.DirectX.dll>
#using <c:\managedDX9dll\Microsoft.DirectX.Direct3D.dll>
using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;
using namespace Microsoft::DirectX;
using namespace Microsoft::DirectX::Direct3D;

__gc class MakeDev : public Form {
private:
Device *device;

public:
MakeDev() {
this->Width = 800;
this->Height = 600;
this->Text = "Managed D3D in C++.net";
}

void inigfx() {
PresentParameters *pp = new PresentParameters();
pp->Windowed = true;
pp->SwapEffect = SwapEffect::Discard;
device = new Device(0,DeviceType::Hardware,this->Handle,
CreateFlags::SoftwareVertexProcessing,pp);
}

void render() {
int i = 1;
this->Show();
while(i==1) {
device->Clear(ClearFlags::Target,Color::Blue,1.0f,0);
device->BeginScene();
device->EndScene();
device->Present();
}
}
};

int main() {
MakeDev *md = new MakeDev();
md->inigfx();
md->render();
return 0;
}



and here's the comparative c# code from the DX9 sdk tutorials:

//-----------------------------------------------------------------------------
// File: CreateDevice.cs
//
// Desc: This is the first tutorial for using Direct3D. In this tutorial, all
// we are doing is creating a Direct3D device and using it to clear the
// window.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace DeviceTutorial
{
public class CreateDevice : Form
{
// Our global variables for this project
Device device = null; // Our rendering device

public CreateDevice()
{
// Set the initial size of our form
this.ClientSize = new System.Drawing.Size(400,300);
// And it's caption
this.Text = "D3D Tutorial 01: CreateDevice";
}

public bool InitializeGraphics()
{
try
{
// Now let's setup our D3D stuff
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed=true;
presentParams.SwapEffect = SwapEffect.Discard;
device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);
return true;
}
catch (DirectXException)
{
return false;
}
}
private void Render()
{
if (device == null)
return;

//Clear the backbuffer to a blue color
device.Clear(ClearFlags.Target, System.Drawing.Color.Blue, 1.0f, 0);
//Begin the scene
device.BeginScene();

// Rendering of scene objects can happen here

//End the scene
device.EndScene();
device.Present();
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
this.Render(); // Render on painting
}
protected override void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e)
{
if ((int)(byte)e.KeyChar == (int)System.Windows.Forms.Keys.Escape)
this.Close(); // Esc was pressed
}

/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{

using (CreateDevice frm = new CreateDevice())
{
if (!frm.InitializeGraphics()) // Initialize Direct3D
{
MessageBox.Show("Could not initialize Direct3D. This tutorial will exit.");
return;
}
frm.Show();

// While the form is still valid, render and process messages
while(frm.Created)
{
frm.Render();
Application.DoEvents();
}
}
}
}
}




Note that if I change *pp to *pp[] and set it up as pp[0]->Windowed=...etc., the code compiles, but I get a NullReferenceException when I run the code. I know that there's some C# code that probably can't translate to vc++.net, but what else is there that I must be missing? Surely I think I'd have seen it somewhere in the DX9 docs if VC++.net wasn't fully supported by the managed DX assemblies...

Also, if I can't get vc++.net to work with DX, should I use c++ and unmanaged DX, or go with C# and managed DX?

Share this post


Link to post
Share on other sites
I'd highly recommend C# and MDX, although MDX is still effectivly beta, so there are some pitfalls and it's error reporting isn't up to snuff (well, it's not compared to the rest of .net) It's performance on Ati cards is very good (in some cases better than C++ normal DX. But on nvidia it's pretty much always a bit slower. Plus nvidia drivers seem to have some internal weirdness going on that can cause strange crashes that are hard to debug (with MDX that is).

My view is .net is the way things will be programmed in the furture, java tried but failed, .net may too, but it will happen, so I say use it. There are *lots* of things that you will slap yourself over because they are so simple and just there already. Watch the gradual fall of x86 and unmanaged code. It will happen. It has started already. [wink]

As for the original post's problem you mentioned, I have a vauge memory of that being related to posititoning of the 'using' statements. I think in C++.net you have to be careful where you put the using statements so they do not appear inside another namespace (or something similar). I remember it was actually quite tricky getting it right, but I'm pretty sure I got a very similar error.

Share this post


Link to post
Share on other sites
Error
Quote:
mdx9.cpp(28) : error C2664: 'Microsoft::DirectX::Direct3D::Device::Device(int,Mi
crosoft::DirectX::Direct3D::DeviceType,System::IntPtr,Microsoft::DirectX::Direct
3D::CreateFlags,Microsoft::DirectX::Direct3D::PresentParameters __gc * __gc[])'
: cannot convert parameter 5 from 'Microsoft::DirectX::Direct3D::PresentParamete
rs __gc *' to 'Microsoft::DirectX::Direct3D::PresentParameters __gc * __gc[]'


IIRC the present parameteres it (for some weird reason) expects an array of PresentParameters, as opposed to just the one. AFAIK it only looks at the 1st one however, so that may be worth a try. this is from an old distant memory tho, but Ive definitely had that error before and I'm pretty sure thats how i fixed it.

Neil

Share this post


Link to post
Share on other sites
What surprises me most about PresentParameters is that in C# it works just fine without trying to declare it as an array (although I'm not that knowledgeable in the language, so it could be some under-the-hood thing). Suppose I make the following changes in c++.net so that the code compiles free of errors:

PresentParameters *pp[] = new PresentParameters();
pp[0]->Windowed = true;
pp[0]->SwapEffect = SwapEffect::Discard;

When I run the executable, I get a NullReferenceException before anything happens and the error report always indicates the inigfx() method has something to do with it. As I may have said in previous posts, apparently there are underlying differences in how classes are built/objects are created between c++.net and c#. It's the only answer I can think of...

Share this post


Link to post
Share on other sites
One thing that seems to be different between your code and the c# is

device = new Device(0,DeviceType::Hardware,this->Handle,
CreateFlags::SoftwareVertexProcessing,pp);


and

device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);

The C++ one seems to pass the handle to the window and the c# one just passes the this pointer - maybe this could be an issue?

Neil




Share this post


Link to post
Share on other sites
I thought so at first, but if I replace "this->Handle" with "this" in the C++ code, I get the following error:

mdx9.cpp(29) : error C2664: 'Microsoft::DirectX::Direct3D::Device::Device(int,Mi
crosoft::DirectX::Direct3D::DeviceType,System::IntPtr,Microsoft::DirectX::Direct
3D::CreateFlags,Microsoft::DirectX::Direct3D::PresentParameters __gc * __gc[])'
: cannot convert parameter 3 from 'MakeDev __gc *const ' to 'System::IntPtr'
No constructor could take the source type, or constructor overload resol
ution was ambiguous

this->Handle returned the IntPtr that the constructor needs, so I've been using it. Not inheriting a Form and instead having something like "form" for the parameter gives this error:

mdx9.cpp(30) : error C2664: 'Microsoft::DirectX::Direct3D::Device::Device(int,Mi
crosoft::DirectX::Direct3D::DeviceType,System::IntPtr,Microsoft::DirectX::Direct
3D::CreateFlags,Microsoft::DirectX::Direct3D::PresentParameters __gc * __gc[])'
: cannot convert parameter 3 from 'System::Windows::Forms::Form __gc *' to 'Syst
em::IntPtr'
No constructor could take the source type, or constructor overload resol
ution was ambiguous

...though I thought that every Form is a control by inheritance. Trying to cast a form like "(Control)form" gives a 'cannot cast' error.

Share this post


Link to post
Share on other sites
If you'd like to send me the code files I can try running them in a debugger here (it sounds like your using command line compilers, which probably makes things considerably harder for you). It may help clear up whats what and see how I can help you progress.

Neil

Share this post


Link to post
Share on other sites
For the complete code, just copy the entire C++ code block in the third post (the first post is out-of-date). I am in fact using the command-line compiler from the VC++ 2005 beta since I'd rather not buy VC++.net until I can get it at the educational price and when .NET 2.0 is released. Are there any third-party c++.net IDEs, like c# has with SharpDevelop (#develop)?

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!