-2

Looking to dll import from vssapi.dll,

Looking at the GetSnapshotDeviceName function, and DLL export viewer gives me:

protected: long __cdecl CVssWriter::GetSnapshotDeviceName(unsigned short const * __ptr64,unsigned short const * __ptr64 * __ptr64)const __ptr64
protected: long __cdecl CVssJetWriter::GetSnapshotDeviceName(unsigned short const * __ptr64,unsigned short const * __ptr64 * __ptr64)const __ptr64

Assuming I want the first one, how do I declare the dll import, for instance:

[DllImport("vssapi.dll", EntryPoint = "CVssWriter::GetSnapshotDeviceName", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
private static extern uint GetSnapshotDeviceName(string wszOriginalVolume, out string ppwszSnapshotDevice);

[With or without the ExactSpelling] always gives me the

Unable to find an entry point named 'CVssWriter::GetSnapshotDeviceName' in DLL 'vssapi.dll

error. Variations on the colons (removing etc), and reversing the names (as the decorated version) gave me no joy either.

I know it can work using the decorated name or the ordinal, but I'd like the code to be reasonably portable (decls being compiler dependent, and nothing I've ever seen says ordinals will stay the same in updates either).

Yeah I already know with this dll it won't port to pre Vista ... that I can live with.
Also heard about AlphaVSS too - but for what I need would be like using an aircraft carrier to go fishing on a lake (- and did they really need to make it so ungainly to use?)

Rob
  • 444
  • 3
  • 10

1 Answers1

1

These are C++ instance methods, that is member functions. As such, they cannot be imported using p/invoke. This API for VSS that you are attempting to use is available either as C++ classes, or via COM.

If the functionality that you need is available through the COM interface, then that will be the simplest way for you to proceed. Otherwise you will need to wrap the C++ classes one way or another. Surely the simplest way to do that will be with a mixed mode C++/CLI assembly.

Either way, p/invoke cannot help you here.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • But they **can** be p/invoked using the ordinal or decorated name... my worry though is doing that is less portable because cdecl/ord subject to change if new version released. Want to know how (if possible) to specify EntryPoint not using ord/cdecl. – Rob Jun 29 '15 at 14:49
  • The fact that you can call `GetProcAddress` and obtain a function pointer doesn't mean that you can successfully call the methods. You are going to need to recalibrate your expectations. Do you know what an instance method is? If so then you'll know that there is an implicit `this` pointer passed to the method. Ask yourself 1. from where you could get that pointer in your C# code given that you cannot call a C++ constructor, and 2. how the function receives that `this` pointer given that you are not passing it. – David Heffernan Jun 29 '15 at 14:51
  • OK, I was wrong, you are correct (upvoted your response)... I get it now when you mentioned the lack of the 'this' instance (as a simple function I guess was just a fluke it did [sort-of?] work, ... but in isolation it wasn't useful anyway.) – Rob Jun 29 '15 at 17:07