Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: C++/CLI component (Read 5694 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

C++/CLI component

Hi,
My goal is to write a WCF service to expose playback_control and playlist_manager in order write a winrt player using foobar2000 as the backend. This requires a C++ to .NET bridge. I was hoping to use a combination of reverse p/invoke and C++/CLI aggregation/composition to accomplish this.

The inititquit implementation is straight up inheritance coupled with initquit_factory_t. This works fine with reverse p/invoke.

I'm puzzled with the playback_control implementation which seems to use composition on the C++ side via static_api_ptr_t<playback_control>. This should not be a problem to then use composition on the C++/CLI side except for the fact that when I include foobar2000.h in a .cpp compilation unit compiling with the /clr switch I get the following errors:

Before initguit::on_init
First-chance exception at 0x75204b32 in foobar2000.exe: Microsoft C++ exception: foobar2000_io::exception_io_data_truncation at memory location 0x0031e91c.
First-chance exception at 0x75204b32 in foobar2000.exe: Microsoft C++ exception: foobar2000_io::exception_io_not_found at memory location 0x0031e940.
First-chance exception at 0x75204b32 in foobar2000.exe: Microsoft C++ exception: foobar2000_io::exception_io_not_found at memory location 0x0031e940.

initguit::on_init gets called and everytings seems ok, then I close the application

On exit of the application:
First-chance exception at 0x75204b32 in foobar2000.exe: 0xC0020001: The string binding is invalid.
Unhandled exception at 0x75204b32 in foobar2000.exe: 0xC0020001: The string binding is invalid.

And it crashes Visual Studio bad, I have to restart the IDE.

Any ideas to solve this? Am I using playback_control correctly? I created a C++ wrapper class which just forwards each function call to the aggregate member static_api_ptr_t<playback_control>.

EDIT: Just to clarify, I need to declare wcf service class objects in the on_init implementation and unfortunately wcf requires instantiable objects in these methods, interfaces are not allowed, thus the problem of requiring to #include foobar2000.h in the /clr compilation unit which implements the service. If I can use the "factory" paradigm for playback_control like is used for initquit perhaps I can use reverse p/invoke for these interfaces?

Thanks.

C++/CLI component

Reply #1
C++/CLI requires linking to Multithreaded DLL crt, so I had to compile the shared libs thus. Is this supported?

Also, probably not an issue, but just curious, the readme file says:
"shared.dll (various helper code, mainly win32 function wrappers taking UTF-8 strings)"
why does shared.dll use UTF-8 strings when Windows internally uses UTF-16.

C++/CLI component

Reply #2
C++/CLI requires linking to Multithreaded DLL crt, so I had to compile the shared libs thus. Is this supported?
Yes, it is. The default settings use the static-linked runtime to simplify the distribution of components.

why does shared.dll use UTF-8 strings when Windows internally uses UTF-16.
foobar2000 has used UTF-8 internally for as long as I can remember, i.e. at least since version 0.4.2. The 0.4.x series added compatibility with Windows 98 while older versions worked exclusively under NT based versions of Windows. So shared.dll was part of the Unicode/ANSI abstraction layer.

C++/CLI component

Reply #3
Thanks Foosion.

Most of my first post was a confusion of how static_api_ptr_t<> works... static_api_ptr_t<> allows for the isolation required.

I managed to get a wcf client to call into a service hosted by Foobar2000.

The problem now is that the following function, compiled in a C++ compilation unit, throws an SEH exception back to the .net client, i.e. it is not handled.

My guess is that it is a thread issue. Is playback an I/O function that requires being called on the main thread? If so, any ideas on how to do that?

Code: [Select]
void abc_playback_manager::Play() 
{
    static_api_ptr_t<playback_control> pbc;
    try
    {
        pbc->start(playback_control::track_command_play);
    }
    catch(pfc::exception const&  ex)
    {
        assert(false);
    }
}




C++/CLI component

Reply #5
My guess is that it is a thread issue. Is playback an I/O function that requires being called on the main thread? If so, any ideas on how to do that?
That is right. See the detailed description of the playback_control class. There you will also find a reference to the main_thread_callback that kerpondile has pointed out.

 

C++/CLI component

Reply #6
Awesome, I had no idea you had compiled a doxygen help system. Thanks again Foosion.