Page 5 of 17 FirstFirst 123456789101112131415 ... LastLast
Results 41 to 50 of 162

Thread: CarMa 2011 (public beta) [updated 14-04-2011] *old thread*

  1. #41
    jsn
    jsn is offline
    Constant Bitrate
    Auto Apps:loading...
    jsn's Avatar
    Join Date
    Jun 2008
    Location
    Zoetermeer, Netherlands
    Posts
    159
    When CM loads a .NET plugin, it has to do it a COM-like way.
    (it's not just LoadLibrary. The binary structure is completely different and an assembly
    contains classes, not just classless exported functions)

    It's not needed if .NET is able to export a method which gives an interface to the object.
    But I'm not sure if thats possible in C#? If it is, it can be the exported "ICMBasePlugin StartPlugin();" method,
    which is also used in the Win32 plugins.

    Otherwise I need an extra piece of information which tells CM to create the correct object
    from the right namespace and class. That's where the XML comes in.

    Maybe a .NET guru can come in and drop a few cents

  2. #42
    jsn
    jsn is offline
    Constant Bitrate
    Auto Apps:loading...
    jsn's Avatar
    Join Date
    Jun 2008
    Location
    Zoetermeer, Netherlands
    Posts
    159
    The major issue is that I'm developing on the Win32 platform, not the .NET platform.
    Right now, I'm translating the interfaces and after that, I'll try loading a small useless
    .NET plugin into Win32 CM.

    It's just not 'natural' to load and use binaries from a different platform..
    There are some tricks I'm able to try out, and it is probably going to work.
    Plugin developers will have to follow a few guidelines to make a good plugin.
    (don't worry, it's just that a couple of basic methods need to be implemented f.i.)

  3. #43
    FLAC SFiorito's Avatar
    Join Date
    May 2004
    Posts
    1,365
    http://www.codeproject.com/KB/cs/ManagedCOM.aspx

    If the .NET objects are exposing COM interfaces, then you can use the above. Otherwise, you would need to host the CLR in your process.
    EWF, HORM, MinLogon on XP.

    Zotac ION Atom N330, 2GB low-profile RAM, M3-ATX
    Win Embedded Std 2011 RC
    OCZ Vertex Turbo 30GB SSD
    Lilliput 629 Transflective, WRX Screen Mount
    BlueSoleil BT, i-Blue GM-2 GPS, DirectedHD Radio, Andrea Mic
    VoomPC 2

  4. #44
    jsn
    jsn is offline
    Constant Bitrate
    Auto Apps:loading...
    jsn's Avatar
    Join Date
    Jun 2008
    Location
    Zoetermeer, Netherlands
    Posts
    159
    Yes, and I think the COM way is the easiest way to go..
    I'm already porting the interfaces from Delphi to C#.. I hope I can run a sample soon..
    It will answer some of your questions about the requirements, I hope.

    But I still need to know the name or GUID of the plugin to load/initiate..
    I'll have to check if there is a way to query the registry for certain interfaces.

    Don't forget, it's a Delphi/Win32 project, not a C#/.NET project..
    We're trying to get them to run together.. Regarding RR and RevFE, they use
    a complete different process. But lets just wait for the sample to arrive in a couple
    of hours/days :s

  5. #45
    FLAC SFiorito's Avatar
    Join Date
    May 2004
    Posts
    1,365
    So, it's been a looong time since I've done Win32 and COM stuff... That's actually what I did a lot of in the late 90's before moving on to Java & .NET, but anyways after some time I think I figured out what it is you need to do. Now, keep in mind this may not be following best practices, but it seems to be working in some tests I tried.

    First, you need to define your COM interfaces. You can do this in IDL:

    Code:
    [
    	uuid(D13B66C0-458F-478C-94EA-703BC1F559D6),
    	version(1.0)
    ]
    library Plugins
    {
    	import "oaidl.idl";
    	import "ocidl.idl";
    	importlib("stdole2.tlb");
    
    	interface ITuner;
    
    	[
    		uuid(77C2AC04-AAA4-4B0F-BE31-59B2306B5E68)
    	]
    	interface ITuner : IUnknown
    	{
    		HRESULT TuneChannel([in] double channel);
    		HRESULT CurrentChannel([out, retval] double* channel);
    	};
    };
    Then, create a typelib using midl:

    Code:
    midl Plugins.ild /tlb Plugins.tlb
    Then, if you're creating COM objects in C++ or VB6 you're done. If you (or 3rd parties) want to develop .NET plugins, you need to create an interop DLL from that typelib:

    Code:
    tlbimp Plugins.tlb /keyfile:mykey.snk /out:Plugins.cs
    We also need to install this assembly in the GAC so all COM objects can reference it and register it:

    Code:
    gacutil /i Plugins.dll
    regasm Plugins.dll
    Now, create a project referencing this assembly, implement a concrete impl using the ITuner interface, make sure the ComVisible attribute is true, sign the assembly, and build. For example:

    Code:
    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using Plugins;
    
    [assembly: ComVisible(true)]
    [assembly: Guid("631717cd-91b3-4b4e-a8f4-5278111bd7c5")]
    namespace MySamplePlugins
    {
        [ClassInterface(ClassInterfaceType.None)]
        [Guid("540287F0-D790-4AB5-9C42-65D19DEDF99A")]
        public class SampleTuner : ITuner
        {
            private double channel = 101.1;
    
            public void TuneChannel(double channel)
            {
                Trace.TraceInformation("Tuning channel {0}", channel);
                this.channel = channel;
            }
    
            public double CurrentChannel()
            {
                return channel;
            }
        }
    }
    Code:
    gacutil /i MySamplePlugins.dll
    regasm MySamplePlugins.dll
    OK! Now, in your Win32 app you just need to use the COM interfaces you defined in the IDL:

    Code:
    #include "stdafx.h"
    
    #import "../Plugins.Interfaces/Plugins.tlb" named_guids raw_interfaces_only
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	CoInitialize(NULL);
    
    	Plugins::ITunerPtr pTuner;
    
    	double channel = 103.5;
    	HRESULT hresult = pTuner.CreateInstance("MySamplePlugins.SampleTuner");
    	if (hresult == S_OK)
    	{
    		hresult = pTuner->TuneChannel(channel);
    		channel = 0.0;
    		hresult = pTuner->CurrentChannel(&channel);
    		printf("Tuned to channel %f\n", channel);
    	}
    
    	CoUninitialize();
    
    	return 0;
    }

    Hope that helps!!! Like I said, some of this may be better in another way, but this worked for me. Gave me something to think about on this snow day!
    EWF, HORM, MinLogon on XP.

    Zotac ION Atom N330, 2GB low-profile RAM, M3-ATX
    Win Embedded Std 2011 RC
    OCZ Vertex Turbo 30GB SSD
    Lilliput 629 Transflective, WRX Screen Mount
    BlueSoleil BT, i-Blue GM-2 GPS, DirectedHD Radio, Andrea Mic
    VoomPC 2

  6. #46

  7. #47
    jsn
    jsn is offline
    Constant Bitrate
    Auto Apps:loading...
    jsn's Avatar
    Join Date
    Jun 2008
    Location
    Zoetermeer, Netherlands
    Posts
    159
    Quote Originally Posted by SFiorito View Post
    So, it's been a looong time since I've done Win32 and COM stuff... That's actually what I did a lot of in the late 90's before moving on to Java & .NET, but anyways after some time I think I figured out what it is you need to do. Now, keep in mind this may not be following best practices, but it seems to be working in some tests I tried.

    First, you need to define your COM interfaces. You can do this in IDL:

    Code:
    [
    	uuid(D13B66C0-458F-478C-94EA-703BC1F559D6),
    	version(1.0)
    ]
    library Plugins
    {
    	import "oaidl.idl";
    	import "ocidl.idl";
    	importlib("stdole2.tlb");
    
    	interface ITuner;
    
    	[
    		uuid(77C2AC04-AAA4-4B0F-BE31-59B2306B5E68)
    	]
    	interface ITuner : IUnknown
    	{
    		HRESULT TuneChannel([in] double channel);
    		HRESULT CurrentChannel([out, retval] double* channel);
    	};
    };
    Then, create a typelib using midl:

    Code:
    midl Plugins.ild /tlb Plugins.tlb
    Then, if you're creating COM objects in C++ or VB6 you're done. If you (or 3rd parties) want to develop .NET plugins, you need to create an interop DLL from that typelib:

    Code:
    tlbimp Plugins.tlb /keyfile:mykey.snk /out:Plugins.cs
    We also need to install this assembly in the GAC so all COM objects can reference it and register it:

    Code:
    gacutil /i Plugins.dll
    regasm Plugins.dll
    Now, create a project referencing this assembly, implement a concrete impl using the ITuner interface, make sure the ComVisible attribute is true, sign the assembly, and build. For example:

    Code:
    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using Plugins;
    
    [assembly: ComVisible(true)]
    [assembly: Guid("631717cd-91b3-4b4e-a8f4-5278111bd7c5")]
    namespace MySamplePlugins
    {
        [ClassInterface(ClassInterfaceType.None)]
        [Guid("540287F0-D790-4AB5-9C42-65D19DEDF99A")]
        public class SampleTuner : ITuner
        {
            private double channel = 101.1;
    
            public void TuneChannel(double channel)
            {
                Trace.TraceInformation("Tuning channel {0}", channel);
                this.channel = channel;
            }
    
            public double CurrentChannel()
            {
                return channel;
            }
        }
    }
    Code:
    gacutil /i MySamplePlugins.dll
    regasm MySamplePlugins.dll
    OK! Now, in your Win32 app you just need to use the COM interfaces you defined in the IDL:

    Code:
    #include "stdafx.h"
    
    #import "../Plugins.Interfaces/Plugins.tlb" named_guids raw_interfaces_only
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	CoInitialize(NULL);
    
    	Plugins::ITunerPtr pTuner;
    
    	double channel = 103.5;
    	HRESULT hresult = pTuner.CreateInstance("MySamplePlugins.SampleTuner");
    	if (hresult == S_OK)
    	{
    		hresult = pTuner->TuneChannel(channel);
    		channel = 0.0;
    		hresult = pTuner->CurrentChannel(&channel);
    		printf("Tuned to channel %f\n", channel);
    	}
    
    	CoUninitialize();
    
    	return 0;
    }

    Hope that helps!!! Like I said, some of this may be better in another way, but this worked for me. Gave me something to think about on this snow day!
    Wow! Thanks!.. I didn't expect so much details .
    I am probably halfway this procedure, but this will be of much help I think!
    The only issue I have now is that I only see the interfaces in the assembly,
    but not the implemented object.. (but the trick might be the uuid instead of the guid..
    gotta read more into that, but C# isn't my 'native' language )

    I'll upload the C# assembly I already have in a few moments so you can get an idea
    how these are set up, and which direction I'm probably going..
    There is already an example of how to use the SDK/interfaces..

    BUT.. Most important: I still need to get the assemblies loading and running in CM

  8. #48
    jsn
    jsn is offline
    Constant Bitrate
    Auto Apps:loading...
    jsn's Avatar
    Join Date
    Jun 2008
    Location
    Zoetermeer, Netherlands
    Posts
    159
    Quote Originally Posted by Enforcer View Post
    PS, I can do my plugins in VB6 if the helps.
    Well... I want to try to get it as open as possible.. I'm just not too sure what the
    requirements for VB6 would be. Does it support interfaces? Probably it does, thinking
    about the CoCreate's and late/early bindings etc..

    Doing a quick search now, but I see VB6 only creates ActiveX type DLL's..
    (so it does support interfaces, ActiveX is all about it)
    But that's no problem I think, .NET plugins load quite the same way in CM. (the COM like way)

    So sure! If you want to develop plugins, be my guest, I'll try to help you out as much as I can.
    And since I told you we want to be as open as possible, I'm willing to make adjustments to get your code running!

    This will be a fun challenge!

  9. #49
    FLAC SFiorito's Avatar
    Join Date
    May 2004
    Posts
    1,365
    Quote Originally Posted by jsn View Post
    Wow! Thanks!.. I didn't expect so much details .
    I am probably halfway this procedure, but this will be of much help I think!
    The only issue I have now is that I only see the interfaces in the assembly,
    but not the implemented object.. (but the trick might be the uuid instead of the guid..
    gotta read more into that, but C# isn't my 'native' language )
    You should only really care about the interfaces you defined (e.g. the ITuner interface in my example above). You then need to CreateInstance an object that implements that interface (e.g. MySamplePlugins.SampleTuner). You shouldn't need to actually load the assemblies yourself, let COM interop handle that for you as I did in the Win32 example above:
    Code:
    HRESULT hresult = pTuner.CreateInstance("MySamplePlugins.SampleTuner");
    EWF, HORM, MinLogon on XP.

    Zotac ION Atom N330, 2GB low-profile RAM, M3-ATX
    Win Embedded Std 2011 RC
    OCZ Vertex Turbo 30GB SSD
    Lilliput 629 Transflective, WRX Screen Mount
    BlueSoleil BT, i-Blue GM-2 GPS, DirectedHD Radio, Andrea Mic
    VoomPC 2

  10. #50
    jsn
    jsn is offline
    Constant Bitrate
    Auto Apps:loading...
    jsn's Avatar
    Join Date
    Jun 2008
    Location
    Zoetermeer, Netherlands
    Posts
    159
    I've uploaded a first version of the C# SDK here..
    Please read the notice on this page if you want to use it!

    It's okay for everyone to shoot on it (or me).. I have a bit experience on the .NET
    platform, but this is quite some different game. If you have any suggestions regarding the translation, please do share them.

    Just a small note why we've chosen interfaces: interfaces allow strong-typing and
    knowledge ahead about the framework and it's methods.
    It bypasses late binding where you (and the compiler) don't have any knowledge
    about the framework. Typing errors are caught already at compile time, not during
    runtime. It also forces the developer to implement certain necessary methods.

    Plugins have the GetHost() available, which returns the interface to core of CarMa.
    It's really easy to traverse this interface and it's subsystems. We've tried to keep them
    clean and logical.
    (although some methods are available in the interface, which shouldn't be called from a plugin.
    These methods will be marked later in the code..)

    But feel free to download the SDK C# (yet uncommented) sample,
    it shows at least what I'm trying to do

Similar Threads

  1. upgraded to 2/1/2011 and...
    By tundra2000 in forum Road Runner
    Replies: 9
    Last Post: 02-17-2011, 04:08 PM
  2. iDrive style skin || updated 24.01.2011
    By Konrad in forum RR Skins No Longer Supported
    Replies: 44
    Last Post: 02-02-2011, 12:32 PM
  3. Ces 2011???
    By Sonicxtacy02 in forum MP3Car Gatherings
    Replies: 63
    Last Post: 01-19-2011, 08:08 AM
  4. Replies: 280
    Last Post: 08-23-2008, 05:22 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •