I making a simple game engine with C# (in VB 2008, mostly for myself). There is a main application which does the graphics and stuff, and most of the data from the actually game will be in a dll generated with the tools I would give to the game designer.
I've heard a lot about C# being great for scripting, (and it looks like it would suit my needs better than any other way) but I can't really find an answer of exactly how it's done. I ran into this problem:
I obviously don't want to give out my source code for the main exe but it will contain all the main methods needed for scripting (because they act on the main exe).
How could a dll be generated when it doesn't have a definition of the methods it will be calling in the parent exe? The main exe will have the dll as a dependency to use it. That means that the dll can't have a dependency on the exe which would cause a loop.
I could create another dll that both the exe and the library would use, but then the methods in there wouldn't be able to act directly on the main exe using it.
The only logical solution I came up with is this:
A dll with the bare bones of the class I need.
A dll that contains the game data. This will have a class inherited from dll A.
Exe dependent on both A and B. It will override the A methods that are in B to behave the way that it should.
This doesn't seem too elegant though.
I've seen a lot of words in my research (MAF, MEF, Roslyn, etc.) before I got too tired to read further. I have spent several hours on this alone.
In your opinion, how should I go about doing this? Is there something I'm overlooking?
I don't know where you heard C# is 'great' for scripting. The half-baked attempt of Rosyln is not really "scripting".
Why not try one of those DLR languages - like IronPython and IronRuby?
Also there is Lua binding for .NET.. Most game developers these days do their scripting in Lua. So the modder community will definitely love your Game Engine, if you plan to keep it closed source.
It's sounds like you're mixing up extensibility through dlls and extensibility through scripting.
Let's take the dll approach first.
The standard way to implement this is quite close to what you've outlined:
Have an interfaces.dll
Your entry point dll will take a dependency on the interfaces.dll
Extension dlls will take a dependency on the interfaces.dll
At runtime, to extend main, scan the entention dll for classes which implement the needed interfaces in interfaces.dll, invoke the methods as needed.
For scripting, you'll typically want to use a scripting language - powershell is popular for .Net, and there are also some experiments with JavaScript
Related
I need to add a new component to a C++ Win32 application (no CLR support) and I would like to implement the new component in C# and use WPF. This new component is basically a window with some controls, which I need to launch quickly from an option in the menu of the Win32 application. The new component and the existing application share some int values and both can modify these values and the other should be notified of changes.
What would be the best way to achieve this?
Thanks
If you want to do this without changing your C++ compilation you might look at calling the .NET assembly as via COM. MSDN describes how to expose .NET Framework Components to COM.
The way I've done this is basically:
Make a COM friendly class and interface in C#
Export the TLB from the DLL
GAC the DLL
Register the DLL using regasm.exe
import the TLB into my C++ code
CoCreateInstance using the __uuidof my C# class
However I haven't tried to do this with a UI component. If the WPF form is a modal dialog you should be OK. If not then I don't know if WPF will be happy with your message loop; you may need to give it a seperate thread so it can run its own loop.
Have you seen the MSDN docs on this subject?
A cursory read implies this is not possible without enabling /clr on your C++ code. if you are able to move to this model then the things you want seem do-able.
btw I would not implement update/signalling code on both sides of the managed/unmanaged boundary for your shared data. Decide where the data lives, and have that code provide a) thread-safe accessors and b) 'update event' wiring that are used by whoever needs to write the data and know about updates.
Check out Observer pattern for a description of how to implement notification to multiple consumers. This may be overkill for your case but useful background.
EDIT:
Until you get the two modules coresident, discussion of event notification design seems premature. If you really cannot build your native code with /clr then I don't see how your WPF component can be used without a separate process, and resulting complexity in interaction and performance hit. Can you re-implement this WPF functionality in native code?
On the other hand - if you plan on making more mods to this codebase, perhaps it's worth considering how hard it would be to port the native code to be /clr-ready. Inline assembler does not prevent use of /clr but it does make it harder, as I am sure you have seen here. My guess is that this would be less work than wiring up the WPF code externally.
The path of least resistance at this point may be to replicate your WPF component in native code. Long term taking the pain of converting your app to /clr may provide a better foundation though. Sorry there is no simple answer.
One way to achieve this is compile your C++ application as a C++/CLI application. Once it's a C++/CLI app, you can mix managed and native code easily, and even talk to managed components with ease.
Rather than mess with COM, I'd prefer to use C++/CLI as a glue layer - that does not require recompiling your entire app as C++/CLI.
That means:
Write the C# code you want.
Write a thin C++/CLI wrapper. This can reference (i.e. dynamically link) to the C# app. All it does is expose a native API around the .NET API. It takes some getting used to, but you can do pretty complex stuff here, including fairly fancy automagic interop via marshal_as. You'll compile this into a dll - a mixed mode DLL.
Your main app now links dynamically to the mixed mode DLL and includes the headers for its API. It can call functions as usual.
This is quite a bit nicer that COM, I think: it doesn't require the GAC, it has a lower overhead should performance ever matter, and exchanging complex datastructures including callbacks & deep object graphs is possible (though there is a learning curve here) quite cleanly by adding custom marshal_as templates/overloads.
I need to port a C/C++ unmanaged project (VS 2008) to C# (preferably .net 3.5).
Are there any conversion-helping
tools; let's say something
translating the code syntax and
asking you verifications/modifications for each
problematic point (I guess I'm dreaming...)
Where can I find some useful howtos or articles about this translation.
They would be very useful if they contained specific hints like:
extern variables should be set in public static classes
(I don't know, I'm guessing...)
Please no suggestion like "You can call your c++ dll from .net", because I know it's possible, but just I can't.
Note:
The C/C++ project uses only STL and
other basic functions, no 3rd Party
libraries etc.
I can't use it directly or wrapped
from C# because our company needs to
mantain/modify the code and we're extremely
more skilled in C# than in C++.
It will cost you far more to convert it than to wrap it and pay a freelancer (like me) to help you out by changing the C++ code for you every few months (or every few years) when you need to make a change. There are some mechanical approaches but the bigger issue is that you can never really be sure that the new C# code does exactly what the old C++ code did. I have clients who have tried this and most gave up and threw the work away. The ones who succeeded did it very slowly, like this:
First, you wrap the old library and get your UI or whatever the new code is (web service, whatever) successfully calling the old library. This gets everyone some "bang for the buck" and buys you time to solve the "we can't maintain our old code" problem. You also develop a comprehensive test suite that proves what the old library does for various edge cases and strange things that only happen in the wild every few years. Over time, you move functionality from the old library into a new C# one and change the calling code to use the new library for that functionality. You move the most volatile parts, the things you change most often, out first. At every stage you run the test cases again to make sure your translation from C++ to C# didn't mess up the results it calculates. Maybe some of it you never move out, maybe in the end it is all moved. You stop when you feel the risk of being unable to maintain your own library and needing to pay someone to do it for you has dropped below the cost of continuing to translate it.
I recommend you have access to someone with good C++ skills when you start. You will probably run into things that don't make much sense to you. But you can get the value from the library pretty quickly, and still solve your underlying problem in the long term.
Depends on what you mean by port.
You can rewrite some of the stuff in C#. Not everything. Some HW or legacy libraries would have to be handled with C/C++ even if you port your own code. I don't know of any reliable automatic converter for C++->C#, and I doubt one can exist.
A better idea may be to wrap your existing code in new C# code. You could create an interop layer in C++/CLI, for example. Or you can communicate with your native code with something like Google Protocol Buffers, if you don't want to mix native/managed code in the same process.
I doubt code conversion tools would help. If you need to make some C++ work in some fashion with .NET, the easiest way is to write a managed C++ layer that wraps it and provides an interface for .NET apps to work with. But it depends on the code.
What is the purpose of rewriting and what does your code do? Does it interface with other components? Does it have a GUI? Is it a standalone executable or a library? Is it a COM / ActiveX server or does it use COM components? Does it link to other DLLs or use 3rd party libraries?
All these affect how you're going to port / rewrite from scratch your app. For example, if your code is an MFC app you may as well forget trying to salvage much code. If your app does http / high level networking stuff you may as well write from scratch. If your code low level you might have to refactor with some C# and some C++ accessible through a managed C++ layer.
Lots of choices and it really depends what your app is doing, how it was written etc.
I as of yet, have not had a need to create a dll in .NET as my programs tend to be distinct from one another (and I haven't programmed for too long). However I am starting to gather a library of regularly used methods now which tend to have copies in lots of my programs (or similar methods that could be made more generic).
As I understand it a dll should be created to share common methods between programs.
So I can put my methods in the dll, what about things like custom dialog boxes and common forms. I currently have a custom error form and a print preview dialog which are used in almost all my programs. Is it good practice to put these in a dll?
"Good practice" in this case really relies on how much code-duplication you're cutting down on. If these dialogues are used throughout a lot of your programs and they take up a lot of code, then yes, it's probably a good idea to move them to a shared space.
But don't be tempted to throw everything in there. You'll find yourself having to override it and by that point you're probably writing more code than you were before. Keep things simple. Keep them generic. Keep them useful.
Before you start, though, be aware that you are creating a dependency tree. If you update your library chances are you'll have to put in some time maintaining your apps that use it... But this is no different from using a third-party lib.
To create a new dll, you just add new project (library) to your solution, and add it as a project reference to your main programme.
It is possible to put anything you want to this project. All dialog boxes, user controls, etc. are just classes, so you can share them as easily as any other class. I think it is good practise to share as much as possible.
Sure why not?
What you're building here is actually a small framework, pretty much like the .Net framework itself. Everything that you think is common between your applications can be put in the assemblies: forms, methods, business logic, exceptions, common data access.
When your framework grows you might want to split up that common DLL. For example if you have common forms in a DLL and you also develop batch applications then they don't need to reference to the DLL containing the WinForms specific classes.
Alternatively you can put the source files for these methods in a common place and just add them as links when you include them in your project/solution.
I just got handed an SDK made of C++ dll, lib, exe, and various .h files. I presume it is meant for C++ developers. The sample projects they provide with their documentation are all written in C++. I am able to spin them up with Visual Studio 8 (2005) and run them. They do control the device as advertised. However the project this needs to be used by is in C# .Net 2.0 and that is unchangeable.
My boss was a C++ developer and says all I need to do is to compile it as a COM object and then import the COM object into my C# solution. My boss says it should take less than an hour to "wrap" there SDK up as a COM object, even for me with no knowledge of C++ compiling.
I've used COM objects in C# solutions before so once this is made, I can continue on from there without a problem.
However, I don't know what to do to make the COM object from the 2 .dll files, 1 .exe, 1 .lib file, 1 .xml file, and the 12 .h files. Is there a resource available to tell me what to do to make this happen?
My boss was a C++ developer and says all I need to do is to compile it as a COM object and then import the COM object into my C# solution.
That's true, however compiling it as a COM object is "difficult" (by which, I mean that you can't do it) unless it already implements the COM APIs (if it doesn't then you need to implement the COM APIs before you can build it as a COM object).
There are books (for example, Essential COM) which explain how to to create COM objects using C++, but it's non-trivial (for building COM objects there may be better books than Essential COM, and better/easier tools than C++).
I think you and/or your boss have 3 options:
Ask the vendor to give them to you as COM objects
Design a COM API that would wrap the SDK's API. Create a COM project (in the language of your choice) which exports this API. Implement these APIs by invoking the underlying SDK methods. To do this you may need someone who knows C++, or be willing to spend much, much longer than "an hour" on this project.
Forget about using COM; instead, build the SDK as a DLL, and use PInvoke to invoke it from .NET code.
My boss says it should take less than an hour to "wrap" there SDK up as a COM object, even for me with no knowledge of C++ compiling.
Based on what you've said I don't know of any way to make that happen.
Tell your boss if it would take him less than an hour to wrap it up, he should certainly do it: it would be a more efficient use of both your time.
I would also suggest ATL (not using attributes), but this is something which can take some time to get right if you're not experienced.
My boss says it should take less than
an hour to "wrap" there SDK up as a
COM object, even for me with no
knowledge of C++ compiling.
That may be true for an experienced C++/COM developer, but not for a beginner. I think your best bet is to use ATL. Take a look at the MSDN tutorial.
And do not use attributes.
This doesn't quite answer your question, but...
One option instead of trying to make a COM object is to use P/Invoke and just call the methods in the DLL.
This thread on the MSDN Forums documents how to make a DLL to call using P/Invoke.
Of course if you need access to a whole class (and make an instance of said object), this isn't going to be helpful.
It's good that the code compiles and runs for you. That said it's totally unfair to assume you can do this in an hour.
Have you checked to see what is actually being built by Visual Studio. There could be a chance that it is already building a COM object.
Investigate how the code is being called. I assume you have a .exe that you can run to test the code. Step through this in the VC++ debugger (it's similar enough to debugging C# code) and try to identify any API calls that match with your docs/expectations. This knowledge will be helpful if you try to go the P/Invoke route.
Something else to consider is SWIG. This is typically used by Python developers to wrap C/C++ code and provides some support for C#.
The managed C++ route is probably more advisable for experienced C++ devs because you need to understand a lot about memory allocation, for all but the simplest code.
I (well, really my lead and I) will first try using p/Invoke (via the DllImport feature of System.Runtime.InteropServices) against the SDK's dll the company provided. I'll let you know how it goes.
I think what you really want/need is C++/CLI, that way you can just build them directly into a managed assembly. The idea is that you write a pretty plain wrapper that looks like kind of a cross between C# and C++ and then it does the rest.
I have a little game written in C#. It uses a database as back-end. It's
a trading card game, and I wanted to implement the function of the cards as a script.
What I mean is that I essentially have an interface, ICard, which a card class implements (public class Card056: ICard) and which contains a function that is called by the game.
Now, to make the thing maintainable/moddable, I would like to have the class for each card as source code in the database and essentially compile it on first use. So when I have to add/change a card, I'll just add it to the database and tell my application to refresh, without needing any assembly deployment (especially since we would be talking about 1 assembly per card which means hundreds of assemblies).
Is that possible? Register a class from a source file and then instantiate it, etc.
ICard Cards[current] = new MyGame.CardLibrary.Card056();
Cards[current].OnEnterPlay(ref currentGameState);
The language is C# but extra bonus if it's possible to write the script in any .NET language.
Oleg Shilo's C# Script solution (at The Code Project) really is a great introduction to providing script abilities in your application.
A different approach would be to consider a language that is specifically built for scripting, such as IronRuby, IronPython, or Lua.
IronPython and IronRuby are both available today.
For a guide to embedding IronPython read
How to embed IronPython script support in your existing app in 10 easy steps.
Lua is a scripting language commonly used in games. There is a Lua compiler for .NET, available from CodePlex -- http://www.codeplex.com/Nua
That codebase is a great read if you want to learn about building a compiler in .NET.
A different angle altogether is to try PowerShell. There are numerous examples of embedding PowerShell into an application -- here's a thorough project on the topic:
Powershell Tunnel
You might be able to use IronRuby for that.
Otherwise I'd suggest you have a directory where you place precompiled assemblies. Then you could have a reference in the DB to the assembly and class, and use reflection to load the proper assemblies at runtime.
If you really want to compile at run-time you could use the CodeDOM, then you could use reflection to load the dynamic assembly. Microsoft documentation article which might help.
If you don't want to use the DLR you can use Boo (which has an interpreter) or you could consider the Script.NET (S#) project on CodePlex. With the Boo solution you can choose between compiled scripts or using the interpreter, and Boo makes a nice scripting language, has a flexible syntax and an extensible language via its open compiler architecture. Script.NET looks nice too, though, and you could easily extend that language as well as its an open source project and uses a very friendly Compiler Generator (Irony.net).
You could use any of the DLR languages, which provide a way to really easily host your own scripting platform. However, you don't have to use a scripting language for this. You could use C# and compile it with the C# code provider. As long as you load it in its own AppDomain, you can load and unload it to your heart's content.
I'd suggest using LuaInterface as it has fully implemented Lua where it appears that Nua is not complete and likely does not implement some very useful functionality (coroutines, etc).
If you want to use some of the outside prepacked Lua modules, I'd suggest using something along the lines of 1.5.x as opposed to the 2.x series that builds fully managed code and cannot expose the necessary C API.
I'm using LuaInterface1.3 + Lua 5.0 for a NET 1.1 application.
The issue with Boo is that every time you parse/compile/eval your code on the fly, it creates a set of boo classes so you will get memory leaks.
Lua in the other hand, does not do that, so it's very very stable and works wonderful (I can pass objects from C# to Lua and backwards).
So far I haven't put it in PROD yet, but seems very promising.
I did have memory leaks issues in PROD using LuaInterface + Lua 5.0, therefore I used Lua 5.2 and linked directly into C# with DllImport. The memory leaks were inside the LuaInterface library.
Lua 5.2: from http://luabinaries.sourceforge.net and http://sourceforge.net/projects/luabinaries/files/5.2/Windows%20Libraries/Dynamic/lua-5.2_Win32_dll7_lib.zip/download
Once I did this, all my memory leaks were gone and the application was very stable.
The main application that my division sells does something very similar to provide client customisations (which means that I can't post any source). We have a C# application that loads dynamic VB.NET scripts (although any .NET language could be easily supported - VB was chosen because the customisation team came from an ASP background).
Using .NET's CodeDom we compile the scripts from the database, using the VB CodeDomProvider (annoyingly it defaults to .NET 2, if you want to support 3.5 features you need to pass a dictionary with "CompilerVersion" = "v3.5" to its constructor). Use the CodeDomProvider.CompileAssemblyFromSource method to compile it (you can pass settings to force it to compile in memory only.
This would result in hundreds of assemblies in memory, but you could put all the dynamic classes' code together into a single assembly, and recompile the whole lot when any change. This has the advantage that you could add a flag to compile on disk with a PDB for when you're testing, allowing you to debug through the dynamic code.
Yes, I thought about that, but I soon figured out that another Domain-Specific-Language (DSL) would be a bit too much.
Essentially, they need to interact with my gamestate in possibly unpredictable ways. For example, a card could have a rule "When this cards enter play, all your undead minions gain +3 attack against flying enemies, except when the enemy is blessed". As trading card games are turn based, the GameState Manager will fire OnStageX events and let the cards modify other cards or the GameState in whatever way the card needs.
If I try to create a DSL, I have to implement a rather large feature set and possibly constantly update it, which shifts the maintenance work to another part without actually removing it.
That's why I wanted to stay with a "real" .NET language to essentially be able to just fire the event and let the card manipulate the gamestate in whatever way (within the limits of the code access security).
The next version of .NET (5.0?) has had a lot of talk about opening the "compiler as a service" which would make things like direct script evaluation possible.