1

UPD I placed VS2010 solutions here. Starting new bounty. I need to to implement own ValueMessageBuilder from .NET. If C++ code need to be written then I'm looking for someone who can show me how to do that and how to link it with C#

I've decided to implement abstract class that comes from dll, so I wrote trivial code

class MyMessageBuilder : DNMessageBuilder
{
}

as DNMessageBuilder is abstract I clicked "Implement members" feature in VS2010, and code was changed to:

class MyMessageBuilder : DNMessageBuilder
{
    public override ValueMessageBuilder* builder()
    {
        throw new System.NotImplementedException();
    }
}

However I have compilation error:

Pointers and fixed size buffers may only be used in an unsafe context

'QuickFAST.Messages.ValueMessageBuilder' is inaccessible due to its protection level

Inconsistent accessibility: return type 'QuickFAST.Messages.ValueMessageBuilder*' is less accessible than method 'Myproj.Fast.MyMessageBuilder.builder()'

Cannot access internal struct 'ValueMessageBuilder' here.

How I supposed to implememnt abstract class DNMessageBuilder, how can I solve my problem? I need to provide custom (written by me) ValueMessageBuilder.

ValueMessageBuilder.h if this is important.

Implementation of abstract class I want to implement

ValueMessageBuilder description

Oleg Vazhnev
  • 23,239
  • 54
  • 171
  • 305
  • 5
    Sounds like ValueMessageBuilder is defined as `internal` so you're out of luck. You have to request new DLL where it's `public`. – Shadow The GPT Wizard Apr 17 '12 at 07:19
  • 1
    Does the answer to this question help? http://stackoverflow.com/questions/920844/c-sharp-how-to-access-internal-class-from-external-assembly – Anya Shenanigans Apr 17 '12 at 07:20
  • Does the DLL you've referenced have dependencies? If so, you may also need to reference them in order to have access ValueMessageBuilder – Smudge202 Apr 17 '12 at 07:20
  • @Smudge202 QuickFASTDotNet.dll is added to references. I guess ValueMessageBuilder is defined in QuickFAST.dll (which can be used from C++ etc.), but QuickFAST.dll can't be added to VS reference, VS claims that assembly is not valid. – Oleg Vazhnev Apr 17 '12 at 07:25
  • @ShadowWizard i can't find "internal" keyword in ValueMessageBuilder declaration. linked .h file in description – Oleg Vazhnev Apr 17 '12 at 07:31
  • added more errors from compilier – Oleg Vazhnev Apr 17 '12 at 07:35
  • Sorry, thought it's a .NET DLL didn't notice it was created in C++ and imported as COM - out of my level of expertise. – Shadow The GPT Wizard Apr 17 '12 at 07:46
  • Did you try making your builder() method internal? That way, if ValueMessageBuilder is indeed internal, it won't be less accessible than your method. – Bob Horn Apr 17 '12 at 11:22
  • @BobHorn yes, it claims that visibility of the method can not be narrowed – Oleg Vazhnev Apr 17 '12 at 16:08
  • 1
    You need to recompile the QuickFASTDotNet.dll (written in C++/CLI) to make the class public/visible (the unsafe warning can be worked around). Unfortunately, the code.google.com/p/quickfast site does not provide any Visual Studio .SLN/.VCPROJ file, so you'll have to figure a way out to recompile the whole quickfast project, plus the DotNet one, as there are a lot of dependencies (boost, etc.). It seems to me the project owners should be able to provide some way to rebuilt that set of libraries. Or else you'll need to dig it out by yourself. – Simon Mourier Apr 28 '12 at 16:22
  • @SimonMourier I'm able to rebuild quickfast (I built x64 version myself) however i'm not sure if this is good idea to change library... But I can try. I will try a little bit later. – Oleg Vazhnev Apr 28 '12 at 16:52
  • @SimonMourier what exact change should I made? I've tried to change `class ValueMessageBuilder : public Common::Logger` to `public class ValueMessageBuilder : public Common::Logger` but this doesn't work. I receive such error `Error C3381: 'QuickFAST::Messages::ValueMessageBuilder' : assembly access specifiers are only available in code compiled with a /clr option F:\Oleg\quickfast_1_4_0_my\src\Messages\ValueMessageBuilder.h 17 1 QuickFAST` – Oleg Vazhnev Apr 29 '12 at 14:21
  • @javapowered - your C++ project needs to be a "CLR" project, that is, either you choose the CLR project type when creating the Visual Studio project, or you ensure "Common Language Runtime Support" is set to "Common Language Runtime Support (/clr)" in the project properties, "General" tab. – Simon Mourier Apr 30 '12 at 06:18
  • @SimonMourier CLR option is set in project properties – Oleg Vazhnev Apr 30 '12 at 06:26
  • @javapowered - strange. Have you put your whole solution with a compiling QuickFAST somewhere? – Simon Mourier Apr 30 '12 at 15:09

3 Answers3

2

After taking a look at your C++/CLI classes i noticed that your ValueMessageBuilder is a pure C++-class not a C++/CLI class it should be.

Therefore this might be a implementation issue, it seems the class is abstract but can only be overriden when using C++/CLI and not C# because it doesn't support C++-only types.

See

http://www.codeproject.com/Articles/17741/C-CLI-in-Action-Declaring-CLR-types

Code

This line is wrong:

class ValueMessageBuilder : public Common::Logger

I don't think it can be changed to a .NET-compatible type because it's working with a lot of C++ objects and types. The only chance you got is: Implement this class in a C++/CLI-type and expose it to C# via another class or interface.

Community
  • 1
  • 1
Felix K.
  • 6,201
  • 2
  • 38
  • 71
  • in Visual Studio i see DNMessageBuilder http://dl.dropbox.com/u/49126809/quickfastDotNetPublicInterface.png But I can't implement it? Why it then shown? What should I do? Should I write something in C++ and then attach that to C# somehow? – Oleg Vazhnev Apr 24 '12 at 07:55
  • @javapowered DNMessageBuilder is a `C++/CLI`-type but `ValueMessageBuilder` isn't. I think the class never intended to be implemented in `C#`. Look at my update, it's possible to write a `C++/CLI` wrapper which can be exposed to `C#`. – Felix K. Apr 24 '12 at 08:00
  • to be honest I don't need "implement" ValueMessageBuilder, I need to return pointer to ValueMessageBuilder from one of my methods. Can I write "unsafe" code for that or something? – Oleg Vazhnev Apr 25 '12 at 03:02
  • To be honest, i don't think you can change the signature of the overriden method, so it would cause a compile-time-error in any case ( Type not found or abstract class not implemented ). So you need to implement it with `C++/CLI`. – Felix K. Apr 25 '12 at 06:16
  • " The only chance you got is: Implement this class in a C++/CLI-type and expose it to C# via another class or interface." - how to do that? I don't understand article you've referenced, it's too complicated for me :) Should I add c++ file to my existent project? Should I create another project? Where I can find an example? Using C++/CLI should I implement `DNMessageBuilder` or `ValueMessageBuilder`? – Oleg Vazhnev Apr 27 '12 at 03:25
  • @javapowered You need to implement the `DNMessageBuilder` in C++/CLI. For this you need to create a new Project which references the C++-Files and the types you want to implement( `DNMessageBuilder` ). You need to hide the class which implements the class and build a wrapper around it ( Another class which allows access to the data of the DNMessageBuilder ). For this you have to use C++/CLI, could be a large task. – Felix K. May 02 '12 at 18:50
0

You can't. If you check QuickFASTDotNet.dll with a decompiler like ILSpy, you'll see that ValueMessageBuilder is internal. In fact, ILSpy shows this code:

using Microsoft.VisualC;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace QuickFAST.Messages
{
    [DebugInfoInPDB, MiscellaneousBits(64), NativeCppClass]
    [StructLayout(LayoutKind.Sequential, Size = 8)]
    internal static struct ValueMessageBuilder
    {
        private long <alignment member>;
    }
}

I'm not into C++, but checking ValueMessageBuilder.h I saw that ValueMessageBuilder has no public modifier (as, for example, DNMessageBuilder has) and according to this guy, classes/structs without visibility modifier will be interpreted as internal. If you really need this, you can add the modifier and then recompile QuickFASTDotNet.dll.

Fernando
  • 4,029
  • 1
  • 26
  • 35
  • but why `DNMessageBuilder` has method that returns `ValueMessageBuilder `. How I supposed to implement `DNMessageBuilder`? – Oleg Vazhnev May 06 '12 at 16:43
-1

The main root of the problem may be related to this (from their documentation page):

Important notice the encoder side of the .NET support in QuickFAST is presently disabled. This is due to some significant improvements that are being made in the encoder. As soon as these encoder changes are stable, the .NET support will be reenabled. If .NET encoding is important to you you can speed this work along by sponsoring it.

More over why do you want to implement DNMessageBuilder? If you only want your own message builder you should inherit ImplBuilderBase which already derives from Messages::ValueMessageBuilder.

Ade Stringer
  • 2,611
  • 17
  • 28
Vipresh
  • 1,250
  • 15
  • 31
  • I do use only decoder which available now (ValueMessageBuilder builds Message from FAST, i.e. accepts data DECODED from FAST). I can not inherit ImplBuilderBase as it it not visible. This is the screenshot of visible members... http://dl.dropbox.com/u/49126809/quickfastDotNetPublicInterface.png – Oleg Vazhnev Apr 19 '12 at 12:08
  • Can U upload the DotNet dll here so I can try it out? – Vipresh Apr 19 '12 at 13:42
  • http://dl.dropbox.com/u/49126809/quickfastx64.zip ask me if you need x86 version and I will post it – Oleg Vazhnev Apr 19 '12 at 16:30