IPB

Welcome Guest ( Log In | Register )

> foobar2000 Development Forum Rules

This forum is for developer discussions only. If you have a problem / bug report / idea / feature request that isn't related to foobar2000 SDK, post it in an appropiate forum instead - tech support questions go to support forum, everything else goes to general forum.
All non-developer posts on this forum will be removed. Continued abuse of this forum will result in admin actions (warnings, account suspension).

 
Reply to this topicStart new topic
How does a plugin tell its version information?
skink
post Feb 28 2013, 23:18
Post #1





Group: Members
Posts: 4
Joined: 28-February 13
Member No.: 106950



Hey!

Today I've managed to write something that doesn't crash the player in C. It was all cool and fun to do that, but I still can't call it a plugin yet. I'm getting a popup message saying

QUOTE
Failed to load DLL: foo_test.dll
Reason: No version information found.


I found the DECLARE_COMPONENT_VERSION macro which declares a class named componentversion_myimpl and a variable called g_componentversion_myimpl_factory. But do I need to pass them to the player? How do I tell it the plugin's version and stuff?

Cheers!
Go to the top of the page
+Quote Post
foosion
post Mar 1 2013, 00:06
Post #2





Group: FB2K Moderator (Donating)
Posts: 4455
Joined: 24-February 03
Member No.: 5153



The version information is mandatory since the ability to check for component updates was added. The DECLARE_COMPONENT_VERSION macro creates an instance of a componentversion service implementation which is added to the list of service implementations exported by the component.

Do you really use C instead of C++?

This post has been edited by foosion: Mar 1 2013, 00:06


--------------------
http://foosion.foobar2000.org/ - my components for foobar2000
Go to the top of the page
+Quote Post
skink
post Mar 1 2013, 00:38
Post #3





Group: Members
Posts: 4
Joined: 28-February 13
Member No.: 106950



Thanks! I suspect the service implementation gets added somewhere at

CODE
static service_factory_single_t<componentversion_myimpl> g_componentversion_myimpl_factory;


But I might be wrong since my C++ knowledge is pretty low. I looked at the declarations of service_factory_single_t and service_impl_single_t, and there was really nothing interesting. Could you point me at the places where the magic happens that adds to and exports that list?

The player calls the only exported function, foobar2000_get_interface, first, then get_version and get_service_list methods of the foobar2000_client implementation. I have a feeling that the return value of get_service_list is exported services (possibly a linked list of them, I'm not sure as the documentation is so brief!), am I right? It's not clear to me how do the services get added though.

QUOTE
Do you really use C instead of C++?

Yes, and it's pure fun!

This post has been edited by skink: Mar 1 2013, 00:39
Go to the top of the page
+Quote Post
Zao
post Mar 1 2013, 18:37
Post #4





Group: Members (Donating)
Posts: 910
Joined: 25-September 03
From: Umeň, Sweden
Member No.: 9001



You should not expect to have much luck using pretty much any part of the foobar2000 SDK from C.
It's all in glorious C++, and many aspects of it mandate inheriting from interfaces and instantiating factory templates with your types.
The only way you could use it from C is if someone makes limited and silly C-style bindings for a subset of the API.


--------------------
Zao shang yong zao nong zao rang zao ren zao.
To, early in the morning, use a chisel to build a bathtub makes impatient people hot-tempered.
Go to the top of the page
+Quote Post
foosion
post Mar 1 2013, 20:17
Post #5





Group: FB2K Moderator (Donating)
Posts: 4455
Joined: 24-February 03
Member No.: 5153



QUOTE (Zao @ Mar 1 2013, 18:37) *
many aspects of it mandate inheriting from interfaces
You can program the virtual funtion pointer tables (vtables) by hand.
QUOTE (Zao @ Mar 1 2013, 18:37) *
and instantiating factory templates with your types.
You can build the list of factory instances in the entry point function before you return it.

I think it is certainly possible even though it may be cumbersome. I remember some guys even had fun writing foobar2000 components in Pascal. Where it gets really tricky are the parts of the API that use C++ exceptions.


--------------------
http://foosion.foobar2000.org/ - my components for foobar2000
Go to the top of the page
+Quote Post
foosion
post Mar 1 2013, 20:19
Post #6





Group: FB2K Moderator (Donating)
Posts: 4455
Joined: 24-February 03
Member No.: 5153



QUOTE (skink @ Mar 1 2013, 00:38) *
Thanks! I suspect the service implementation gets added somewhere at
Yes, the constructor of the factory class does that. Constructors of global variables are run automatically by the C++ runtime, so by the time your component entry function accesses the list, the list already contains all the service factory instances [EDIT] if you use C++[/EDIT].

This post has been edited by foosion: Mar 1 2013, 20:20


--------------------
http://foosion.foobar2000.org/ - my components for foobar2000
Go to the top of the page
+Quote Post
skink
post Mar 2 2013, 13:52
Post #7





Group: Members
Posts: 4
Joined: 28-February 13
Member No.: 106950



Thanks a lot! Armed with a debugger I found the problem yesterday: I were providing the wrong GUID. foobar2000 tests each plugin for the entry point, player version compatibility, valid service list (singly linked), and finally scans the list for a service with m_guid == {10BB3EBD-DDF7-4975-A3CC-23084829453E}, which is obviosly GUID of componentversion.

The other problem I encountered was different calling convention. Methods (non-static only, as Wikipedia ensures) in Visual C++ are getting called using thiscall, i.e. `this` pointer is passed through ECX and the callee cleans the stack. I've been doing that using cdecl, breaking both rules. Luckily, GCC starting with version 4.6 provides __thiscall keyword, which seems to be compatible with VS's thiscall.

I'm now at the stage of implementing pfc::string_base. I'm going to post the code when the proof-of-concept is done, just for fun.

This post has been edited by skink: Mar 2 2013, 13:53
Go to the top of the page
+Quote Post
Zao
post Mar 2 2013, 14:59
Post #8





Group: Members (Donating)
Posts: 910
Joined: 25-September 03
From: Umeň, Sweden
Member No.: 9001



Yes, you can implement a component by using a very small magnet too.
The presence and implementation of vtables is a compiler-specific thing, and is utterly undocumented in the compiler vendors documentation.
If this makes you feel happy, then do so, but for the love of $deity, don't ever release anything based on your reverse-engineered assumptions about the runtime implementation of VC++, because it _will_ be incompete and it _will_ ruin stability of end-user installations of foobar2000.

The last thing I need is to get component crash blame because someone else can't be arsed to use a language properly and instead build a false impression of it, smashing the integrity of the process.

Please, foosion, just because you _can_ implement runtime derivation of types and manual construction of symbols that mangle like C++ doesn't mean that it's remotely "writing components in C".

Your statements can and will be misconstrued by idiots everywhere, and they will fuck up.


--------------------
Zao shang yong zao nong zao rang zao ren zao.
To, early in the morning, use a chisel to build a bathtub makes impatient people hot-tempered.
Go to the top of the page
+Quote Post
Zao
post Mar 2 2013, 15:00
Post #9





Group: Members (Donating)
Posts: 910
Joined: 25-September 03
From: Umeň, Sweden
Member No.: 9001



As for skink - beware of trying to making anything based on reverse-engineered implementation details.
That's in violation of the SDK license and will most probably lead to violent bannination of any released components.


--------------------
Zao shang yong zao nong zao rang zao ren zao.
To, early in the morning, use a chisel to build a bathtub makes impatient people hot-tempered.
Go to the top of the page
+Quote Post
skink
post Mar 2 2013, 16:10
Post #10





Group: Members
Posts: 4
Joined: 28-February 13
Member No.: 106950



QUOTE (Zao @ Mar 2 2013, 15:59) *
Yes, you can implement a component by using a very small magnet too.
The presence and implementation of vtables is a compiler-specific thing, and is utterly undocumented in the compiler vendors documentation.
If this makes you feel happy, then do so, but for the love of $deity, don't ever release anything based on your reverse-engineered assumptions about the runtime implementation of VC++, because it _will_ be incompete and it _will_ ruin stability of end-user installations of foobar2000.

The last thing I need is to get component crash blame because someone else can't be arsed to use a language properly and instead build a false impression of it, smashing the integrity of the process.

Please, foosion, just because you _can_ implement runtime derivation of types and manual construction of symbols that mangle like C++ doesn't mean that it's remotely "writing components in C".

Your statements can and will be misconstrued by idiots everywhere, and they will fuck up.


FWIW, Clang tries to be as much compatible with VS as the patents allow that: https://github.com/llvm-mirror/clang/blob/m...ableBuilder.cpp Apart from the Clang source and VC++ ABI documentation, there are a few articles about reverse-engineering the ABI in the Web. Finally, we all surely know two useful flags: /d1reportAllClassLayout and /d1reportSingleClassLayoutXXXX!

These methods (especially the last one) should be enough for building a stable component for foobar2000 in C. If, for any reason, the ABI changes, either *all* newly built or *all* old plugins will be incompatible with the player, no matter in what language they were written. That's the weak part of the SDK - a C ABI or even COM ABI wouldn't cause this problem. From the top of my head, I could name a foobar2000 component which crashes constantly. Written in C++.

Thanks for calling me an idiot :-) After all, I didn't force anyone to do same thing, neither I did distribute anything. I were just seeking help here.
Go to the top of the page
+Quote Post
foosion
post Mar 4 2013, 17:46
Post #11





Group: FB2K Moderator (Donating)
Posts: 4455
Joined: 24-February 03
Member No.: 5153



Zao: I agree that "technically possible" and "recommendable" are two different things for exactly the reasons you and skink have mentioned. If someone - like skink - seeks a challenge for his or her personal amusement and education, I don't have a problem with that.

I also did not have the impression that skink was interested in making a full-blown component and release it to the public. Even though most obstables can be overcome some way or another, re-implementing a sufficiently large subset of the foobar2000 SDK eventually gets rather tedious and boring because it is repetitive work. wink.gif


--------------------
http://foosion.foobar2000.org/ - my components for foobar2000
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 



RSS Lo-Fi Version Time is now: 26th October 2014 - 00:38