0

I am trying to build The Mypintool sample that comes with pin distribution for x64 architecture. I am using pin3.0 (build 76991) and Visual Studio 2012. The build is successful if I have not included windows.h. But if I include window.h (in a separate namespace) like this:-

namespace WD {
    #include "Windows.h"
}

Then the build gives the error :-

C:\Program Files (x86)\Windows Kits\8.0\Include\um\winnt.h(3486): error C2888: '_CONTEXT::<unnamed-tag>' : symbol cannot be defined within namespace 'WD'
C:\Program Files (x86)\Windows Kits\8.0\Include\um\winnt.h(3488): error C2888: '_CONTEXT::<unnamed-tag>::<unnamed-tag>' : symbol cannot be defined within namespace 'WD'

Also, I am able to build the tool for win32 with windows.h included without any issue. Also, I have compared the build settings for win32 and x64 and I could not find any discrepancy.

Any help is appreciated.

Nishant
  • 2,571
  • 1
  • 17
  • 29
  • 1
    Wrapping the windows header inside a c++ namespace is not supported. If it doesn't work: don't do it. – Chris Becke Aug 01 '16 at 08:14
  • @ChrisBecke Wrapping the windows header inside a c++ namespace works fine for a pintool built for win32 architechture. It is the proposed solution by intel as pin has some conflicts with winapi names. Look here at the pin user guide under section `Conflicts between Pin and Windows` : https://software.intel.com/sites/landingpage/pintool/docs/76991/Pin/html/index.html . – Nishant Aug 01 '16 at 10:26
  • And yet, on x64 bits, it fails. Explicitly telling you it cannot define certain windows symbols in the WD namespace. It doesn't get more clear than that. You could try adding `#define WIN32_LEAN_AND_MEAN` before doing the #include. This makes windows.h omit a number of optional things that might allow it to build. – Chris Becke Aug 01 '16 at 11:24
  • @ChrisBecke I understand that I cannot define certain windows symbols in the WD namspace. But I need to include "windows.h" to use windows APIs. And I cannot do it directly because of conflicts with pin APIs. I also tried `#define WIN32_LEAN_AND_MEAN` but the same error persists. – Nishant Aug 01 '16 at 13:07

1 Answers1

1

It is unclear to me if you have a windows application that makes use of "Pin" or a "Pin" application that needs to call some Windows APIs - or a hybrid where massive use of both APIs exists in a single program.

Nonetheless, the Windows SDK is quite large, and is designed (mostly) to work with C, or with a subset of C++ compatible with C so it cannot be expected to work if wrapped in a namespace.

So, your only effective way to deal with a conflict in headers, is to avoid it by never including the "pin" or "windows" headers in the same cpp file. You need to partition the parts of your program that call windows, and that call "pin" into separate cpp files.

Create a bridging header file that defines classes and functions that use only C++ declarations. As it makes no use of either pin, or windows, this file can be #included by both sides of your project. Of course, depending on what your application is attempting to achieve this may be difficult so you might have to engage in some heavy duty type erasure.

Something like this:

// pin.cpp
#include <intel/pin.h>
#include "bridge.h"

void method(){
  Window* wnd = Window::Create();
  wnd.Show();
}

.

// bridge.h
class Window {
public:
  static Window* Create();
  virtual void Show()=0;
};

.

// WindowsImpl.cpp
#include <windows.h>
#include "bridge.h"

class WindowImpl : public Window {
  HWND hwnd;
public:
  bool Create(){
    hwnd = CreateWindowEx(...);
    return hwnd != NULL;
  }
  void Show() override {
    ShowWindow(hwnd,...);
  }
};
Window* Window::Create(){
  WindowImpl* newWnd = new WindowImpl();
  newWnd->Create();
  return newWnd;
}
Chris Becke
  • 34,244
  • 12
  • 79
  • 148