2

I have to import a few functions of a dll written in C into a VB6 project. I have an example written in C# but I don't really know how to do the same thing in VB6.

In C# it goes like this:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int someCallback(IntPtr ch, uint chL, IntPtr cbData);

[DllImport("someDLL.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int someFunction(IntPtr con, someCallback callback, IntPtr cbData);

Everything works fine in the example when calling someFunction.

The documentation of the dll just gives me this:

typedef int(SOMEAPI_CALL * someCallback)(const unsigned char *ch,
                                         unsigned int         chL,
                                         void                *cbData)

SOMEAPI_CALL someFunction(Con*         con,
                          someCallback callback,
                          void*        cbData)

There should be a way to do the same in VB6 but I don't have that much experience with this language. Searched the web for a good time but didn't find anything that could help me.

I know how to declare functions from that dll in my project but thats that. How to convert this UnmanagedFunctionPointer thingy into VB6 code, I just don't know.

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Rabum Alal
  • 51
  • 5

1 Answers1

2

VB6 has no attributes in the way VB.NET (and C#) does, and the annotation would be unnecessary anyway. You can just pass a function pointer to a C API function via the AddressOf operator:

Declare Function someFunction Lib "someDLL" ( _
    ByVal con As Long, _
    ByVal callback As Long, _
    ByVal data As Long _
) As Long

…

Call someFunction(con, AddressOf SomeCallback, data)

But even that won’t work since VB6 does not support native interop using the cdecl calling convention, it only supports stdcall. You will either need to recompile your DLL using the stdcall calling convention, or create a wrapper in C or IDL (there are some hacks using inline assembly to wrap individual cdecl calls but I wouldn’t recommend using these).

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • Thanks. I tried it like this but i still get an error at the AddressOf part. Says that a sub, function or property are expected. Is there something missing? – Rabum Alal Apr 20 '20 at 09:34
  • @RabumAlal Well did you declare a suitable `SomeCallback` function? – Konrad Rudolph Apr 20 '20 at 11:15
  • Not yet, I'll try that. Question is, is that neccesary? Isnt that function inside that dll? Why declare? Sry for bad english and stupid questions. Still very new in all this. – Rabum Alal Apr 20 '20 at 11:18
  • @RabumAlal in the C# example you pass a C# delegate to the external function. You can think of a delegate as a stand-in for the address of the function you want to be called-back. So you are passing it a function in your own code. – StayOnTarget Apr 20 '20 at 11:42
  • 1
    No, it wouldn't work with `CallingConvention.Cdecl`. – GSerg Apr 20 '20 at 11:45
  • @RabumAlal *The whole point* of calling that function is to pass in a callback that you define in your code. That said, GSerg is right, I had missed that your DLL is using the cdecl calling convention, that won’t work. You will need to either recompile your DLL with stdcall calling conventions or create a wrapper (e.g. a COM wrapper). – Konrad Rudolph Apr 20 '20 at 12:55
  • Cant recompile, since it's a third party dll. I have different versions of that dll and the one i'm using is using stdcall calling conventions. I guess creating a wrapper is the only solution then. – Rabum Alal Apr 20 '20 at 13:41
  • @RabumAlal If you have an stdcall version, then use that, and this answer will work. Just make sure it's a 32-bit one. – GSerg Apr 20 '20 at 14:02
  • It works now. Just had a little problem with AddressOf. Seems like you can't use that in classes. Learned a few things today. Thank you all. – Rabum Alal Apr 20 '20 at 15:57