Category Archives: C++

More adventures with C++/CLI

I’ve been working with C++/CLI to get access to native API functionality from C# some more lately. I’ve been running into cases where something compiles flawlessly when I create the project but then fails miserably when pulled from GIT clean and rebuilt. I’m looking at various build issues that might be contributing to this and will hopefully find the right recipe soon.

Some notes here related to parts that matter and APIs that I’m looking to use…half of this for my own reference as I mess with solutions to see what works:

Marshaling strings the (relatively) easy way:

 #include <msclr/marshal.h>

System::String^ myPath = "ABC";
std::wstring path = msclr::interop::marshal_as(myPath);

File information:

typedef struct _FILE_ID_INFO {
ULONGLONG VolumeSerialNumber;
FILE_ID_128 FileId;
} FILE_ID_INFO, *PFILE_ID_INFO;

FILE_ID_INFO info;

BOOL ok = GetFileInformationByHandleEx(myHandle, FileIdInfo, &info, sizeof(info));

Alternate string marshaling:

inline void MarshalString(String ^ s, std::wstring& os) {
using namespace Runtime::InteropServices;
const wchar_t* chars =
(const wchar_t)Marshal::StringToHGlobalUni(s)).ToPointer();
os = chars;
Marshal::FreeHGlobal(IntPtr((void)chars));
}

Volume information:

BOOL ok = GetVolumeInformationW(path.c_str(),
volumeNameBuffer, MAX_PATH + 1,
&serial,
&pathLength,
&flags,
filesSystemName, MAX_PATH + 1);

File attributes (can be used on c:\ to find things like volume creation time stamp)

WIN32_FILE_ATTRIBUTE_DATA info;     
BOOL ok(GetFileAttributesExW(path.c_str(),
  GetFileExInfoStandard,
static_cast<void *>(&info)));

creationDate = gcnew System::DateTime((long long)(info.ftCreationTime.dwLowDateTime) | ((long long)(info.ftCreationTime.dwHighDateTime) << 32));

Additional volume information:

    wchar_t volumeName[1024];     wchar_t fsName[1024];     DWORD vsn;     DWORD fsflags;     BOOL ok(GetVolumeInformationW(path.c_str(),         volumeName, 1024,         &vsn,         nullptr,         &fsflags,         fsName, 1024));

and

    ULARGE_INTEGER free;     ULARGE_INTEGER total;     ULARGE_INTEGER totalfree;     BOOL ok(GetDiskFreeSpaceExW(path.c_str(), &free, &total, &totalfree));

and basic info

FILE_BASIC_INFO info;
BOOL ok(GetFileInformationByHandleEx(handle, FileBasicInfo, static_cast(&info), sizeof(info)));

JSON over Stdin/Stdout for small local components.

I’m looking at adding a local control capability to my little C++ based file and volume identifier tool. I’ve run into a number of small functions that would be well served by tools written in specific languages that have access to specialized APIs but would benefit from a local interface with somewhat decent performance.

Unix style text in/text out is limiting as the command/response format lacks structure and the performance (with one process start per request) is potentially unacceptable.

Adding in a command line switch that sets the tool into ‘json in/json out’ mode and keeps the program alive until the pipes drop or an exit command is received should address these issues.

Ideally, the stdin and stdout would transport UTF-8 data containing complete JSON entities…one as a request and one containing the complete response. This can continue until the hosting program sends an EOF or drops the pipes.

I’m wrapping together a very lightweight JSON generator/parser to support this effort and will be following that up with some testing of C++/Java/C# (and perhaps others) sub-process and pipe management coding. If all goes well, I should have a nice little approach for wrapping small pieces of code that need to run in a particular language but must be hosted elsewhere with decent performance and a robust communications format.

New Version of the C++ Templates Book

There is a new edition of C++ Templates: The Complete Guide (2nd Edition) out. This has actually been in print for around a year, but I’ve been a bit focused on C#, Java and Javascript and not paying all that much attention to C++ developments for the last couple of years.

I’ve created plenty of template classes and functions in C++ but have not done much more than a bit of reading on the powerful template metaprogramming capabilities provided by the C++ template facility. With C++ 2011/2014/2017 and its language and runtime library enhancements, these sorts of approaches have  become more powerful and less complex.

I expect to buy a copy of this and read it through sometime soon as a complement to The C++ Programming Language, 4th EditionThe C++ Standard Library: A Tutorial and Reference (2nd Edition) and Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14 1st Edition. I’m still considering dropping money on a copy of the standard itself (ISO/IEC 14882:2017 Programming languages — C++, main page here) as the comments on the final draft that is freely available seem to suggest it is more of a mess than is usual. Interesting…the ANSI copy is at $116.00 which is significantly less expensive than I had thought.

JSON over stdin/stdout

I’m looking at adding a json over standard I/O pipes option to my tool from last weekend. I’m thinking of this as an intermediate option between interop type solutions (jni, pinvoke and such) and simple command line execution.

Adding in a –jsonrpc option to the tool that selects a mode where json object are read from stdin and json results are emitted to stdout seems like a pretty good option. This should provide an abstracted but tightly coupled interface between a piece of code running as a separate process and a language that may not have access to the APIs needed to get the job done.

This does imply that there will be one subprocess per parent process that needs access. The upside of this is that things remain modular where a problem with one subprocess has no effect on others in the system. We sacrifice a bit of efficiency along the way, but I can’t see that as a major issue in most cases.

Adding Boost to the mix…

I’ve built and used boost before and had good results. I’m going to add boost to my home C++ tools mix and I suspect I may find a workable json parser/generator in there. Grabbing the pieces now, but I don’t expect that I’ll have a usable build for a day or two given available cycles/time.

Built b2 and now I’ve bootstrapped the zip archive of boost. We’ll see what is there in the morning after the .\b2 run finished. I think I may wind up missing some interesting bits that require optional extras, but I should have a decent subset and can likely add in the missing pieces as needed.

A bit of C++ over the weekend

I spent a good bit of time over the weekend digging into some java coding for work. Wrapping some things up and the extra time will help.

I noticed that there is a third edition of effective java out there. I have the older edition, but it is really too old to be helpful with the current state of the java world. The ‘effective’ books overall have tended to be very helpful with usage, idioms and anti-patterns beyond the basic so I’m looking forward to reading this volume and seeing what it has to offer.

I spent a good piece of today writing up a free-standing command line tool to display the unique file id for windows files. The API that provides this is exceptionally useful when working with file cleanup in systems where there are mount points, symbolic links and other reparse points present. This API is not directly accessible from languages such as java or C# and thus an invokable command line tool seems handy. Interop and jni would also offer access, but the command line tool seems the most general purpose (if perhaps low on the performance scale).

I wound up writing a small command line option parser to support this work (though only used a little at this point). I’ll likely keep this around and use it in other tools going forward.

I’m also looking at adding a json output generation option and a stream in/stream out switch to make this little tool more useful for higher volume solutions with programmatic interfaces. It seems as if a json based programmatic interface using standard I/O streams would offer significant performance while also providing enough ‘traction’ to make program to program use of the tool practical.

I ran into a small hiccup this evening as I was unable to upload the code to github as github appeared to be suffering from some sort of relatively serious failure. Hoping that tomorrow morning things will be in better shape and I can push the code up then.

I will probably build a simple json library for local use over the next couple of days (I’ve done this before and it is relatively straightforward as json is a very regular and simple format). I need small and easy more than capable and fast so something coded locally seems best.

Automation for PDF Viewing

I’ve wanted to automate view management for PDF documents for some time. It would provide a way to make locating the document I want and getting content up on the screen amid a mass of technical documentation much easier (and with the cryptic names that many companies use for their pdf files that can be a big deal).

Ideally I’d like to access the viewer over something like a DCOM automation link with full control over the view state and other particulars. In a pinch, I’d settle for process control, cross process window size and location management and some command line arguments to force the view mode and initial page view.

Here are some pages that might be helpful with this (still reading things but trying to keep a record here).

Another approach would be to find a PDF renderer that can be run inside a C# or C++ process. Looking there as well… Suspecting there may very well be a project or two on GitHub.

Full file ID API in Win32

In order to get the full ID of a file in Win32 the GetFileInformationByHandle  returning a BY_HANDLE_FILE_INFORMATION which contains 64 bits of file ID (and the volume id where the file resides) is a start.

The GetFileInformationByHandleEx  with FILE_INFO_BY_HANDLE_CLASS of returns FILE_ID_INFO which provides the full (potentially) 128 bit file id as required for ReFS.

I’ll likely provide support for both of these shortly, likely using C++/CLI to simplify the interface.

Given these two pieces of information it should  be much safer to clear out duplicate files as various sorts of links and mount points will still show the ultimate file identity properly and avoid deleting apparent duplicates that are really just aliased paths to the same file.