2

I am translating a dll that was written on C#, and I am having some troubles to translate a string declaration. The code in C# is as follows:

using BGMC_TypeDefs;
using stdole;
using System.Runtime.CopilerServices;
using System.Runtime.InteropServices;

namespace bgmcproject
{
  [Guid("3C69B26B-8D17-11D3-BA9C-00E09803AA6A")]
  [ClassInterface(0)]
  [ComSourceInterfaces("bgmcproject.__bgmc\0\0")]
  [TypeLibType(32)]
  [ComImport]
  public class bgmcClass : _bgmc, bgmc, __bgmc_Event
  {
    [DispId(1745027134)]
    public virtual extern string szMachineImg { [DispId(1745027134), MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [param: MarshalAs(UnmanagedType.BStr), In] set; }
  }
}

I already translated some of the code, and I ended up with this:

Imports BGMC_TypeDefs
Imports stdole
Imports System.Runtime.CompilerServices
Imports System.Runtime.InteropServices

Namespace bgmcproject
   <Guid("3C69B26B-8D17-11D3-BA9C-00E09803AA6A")>
   <ClassInterface(0)>
   <ComSourceInterfaces("bgmcproject.__bgmc\0\0")>
   <TypeLibType(32)>
   <ComImport>
   Public Class bgmcClass
      Implements _bgmc, bgmc, __bgmc_Event

      <DispId(1745027134)>
      Public virtual external String szMachineImg _ 
      (<DispId(1745027134), MethodImpl(MethodImplOptions.InternalCall, _
               MethodCodeType = MethodCodeType.Runtime)> _
               <param MarshalAs(UnmanagedType.BStr), In> Set )
   End Class
End Namespace

I would like to know how write the declaration of the szMachingeImg. Also if you can help me to clarify, if the "Implements" statement is correct, or I should write "Inherits". Many thanks in advance.

  • `Implements` is correct for interfaces, `Inherits` is correct for classes. – Craig Jul 18 '17 at 17:42
  • Many Thanks! Any idea of how I could translate "Public virtual external" part? – Luis Enriquez Jul 18 '17 at 18:12
  • `public` maps directly. `virtual` I think would be `Overridable`. I'm not sure about the `extern`, though... this isn't something I've needed to do in VB. – Craig Jul 18 '17 at 18:18
  • Thanks again! You think I could write it like a function? Like this: . Public Overridable Function szMachineImg( Set) As String End Function – Luis Enriquez Jul 18 '17 at 18:33
  • Unfortunately, you've gone beyond my expertise now. Sorry. :( – Craig Jul 18 '17 at 18:34
  • No problem, many thanks for the help! – Luis Enriquez Jul 18 '17 at 18:45
  • You should not be translating this at all. This a COM interop assembly, it is auto-generated when you use Tlbimp.exe or add a reference to the type library. That works in VB.NET as well as it does in C#. – Hans Passant Jul 21 '17 at 14:50

1 Answers1

0

This is a rare use of the extern keyword without an accompanying DllImport attribute. The extern keyword combined with the MethodImpl attribute with the MethodImplOptions.InternalCall enum value signifies that the code is implemented in the CLR itself: How does extern work in C#? (see Dan Abramov's answer).

In VB, I don't think you can specify attributes on a 'set' or 'get' individually unless the property is written in 'long-form', so the VB equivalent to your code should be:

Imports Microsoft.VisualBasic
Imports System.Runtime.CopilerServices
Imports System.Runtime.InteropServices

Namespace bgmcproject
  <Guid("3C69B26B-8D17-11D3-BA9C-00E09803AA6A"), ClassInterface(0), ComSourceInterfaces("bgmcproject.__bgmc" & vbNullChar & vbNullChar), TypeLibType(32), ComImport>
  Public Class bgmcClass
      Inherits _bgmc
      Implements bgmc, __bgmc_Event

    <DispId(1745027134)>
    Public Overridable WriteOnly Property szMachineImg() As String
        <DispId(1745027134), MethodImpl(MethodImplOptions.InternalCall, MethodCodeType := MethodCodeType.Runtime), param:= MarshalAs(UnmanagedType.BStr), [In]>
        Set(ByVal value As String)
        End Set
    End Property
  End Class
End Namespace

Also, regarding whether the first _bgmc type is a class or interface, I'm assuming it's a class, but you would need to check that.

Dave Doknjas
  • 6,394
  • 1
  • 15
  • 28
  • Hey many thanks for the help, everything is fine except for the part including the "param:" part. I tried to write it like: param:=MarshalAs(UnmanagedType.BStr) but it tells me "param" is not defined, also if I put only like "param:". Do I need to import a library? – Luis Enriquez Jul 24 '17 at 17:07
  • @LuisEnriquez: I've updated my answer to use "param := ...". – Dave Doknjas Jul 24 '17 at 18:30
  • Thanks again, I already put it like "`param:=`", but it still tells me that "Type 'param is not defined". I am using visual studio 2017, in the potential fixes it tolds me to use '`[ParamArray]`' or '`DefaultParameterValue`'. If I use `DefaultParameterValue`, It tells me that I need to change the MarshalAs, because it may be inaccessible due to its protection level. So if I put it like `DefaultParameterValue(MarshalAsAttribute(UnmanagedType.BStr))`, the `DefaultParameterValue` is marked as good to go, but now I get an error on `MarshalAsAttribute`. Maybe I am missing some reference for param? – Luis Enriquez Jul 25 '17 at 12:12