I need to create a GUID in an unmanaged windows C++ project. I'm used to C#, where I'd use Guid.NewGuid(). What's the (unmanaged windows) C++ version?
I think CoCreateGuid is what you're after. Example:
GUID gidReference;
HRESULT hCreateGuid = CoCreateGuid( &gidReference );
UuidCreate() in Win32 API has exactly the same effect. However you need to pass an address of the variable that will receive the generated value:
UUID newId;
UuidCreate( &newId );
I believe Guid.NewGuid() simply maps onto it inside the .NET runtime.
Here's a snippet of code to get the resulting string value of the generated GUID:
// For UUID
#include <Rpc.h>
#pragma comment(lib, "Rpcrt4.lib")
int _tmain(int argc, _TCHAR* argv[])
{
// Create a new uuid
UUID uuid;
RPC_STATUS ret_val = ::UuidCreate(&uuid);
if (ret_val == RPC_S_OK)
{
// convert UUID to LPWSTR
WCHAR* wszUuid = NULL;
::UuidToStringW(&uuid, (RPC_WSTR*)&wszUuid);
if (wszUuid != NULL)
{
//TODO: do something with wszUuid
// free up the allocated string
::RpcStringFreeW((RPC_WSTR*)&wszUuid);
wszUuid = NULL;
}
else
{
//TODO: uh oh, couldn't convert the GUID to string (a result of not enough free memory)
}
}
else
{
//TODO: uh oh, couldn't create the GUID, handle this however you need to
}
return 0;
}
API reference:
UuidCreate
UuidToString
RpcStringFree
The documentation for Guid.NewGuid points out, how it is implemented:
This is a convenient static method that you can call to get a new Guid. The method wraps a call to the Windows CoCreateGuid function.
So the native equivalent to Guid.NewGuid() is CoCreateGuid().
CoCreateGuid calls UuidCreate, to generate a GUID. Both API calls are slightly different, though: While UuidCreate returns a UUID, that is guaranteed to be unique to the computer that created it, CoCreateGuid produces a GUID that is absolutely unique.
If you need to decide, which API to use, here are the relevant sections from the documentation.
UuidCreate:
For security reasons, it is often desirable to keep ethernet addresses on networks from becoming available outside a company or organization. The UuidCreate function generates a UUID that cannot be traced to the ethernet address of the computer on which it was generated. It also cannot be associated with other UUIDs created on the same computer.
CoCreateGuid:
The CoCreateGuid function calls the RPC function UuidCreate, which creates a GUID, a globally unique 128-bit integer. Use CoCreateGuid when you need an absolutely unique number that you will use as a persistent identifier in a distributed environment.
To generate a new guid in windows and get the resulting value as a string.
#include <string>
#include <sstream>
#include <iostream>
#include <windows.h>
#include <iomanip>
int main()
{
GUID guid;
CoCreateGuid(&guid);
std::ostringstream os;
os << std::hex << std::setw(8) << std::setfill('0') << guid.Data1;
os << '-';
os << std::hex << std::setw(4) << std::setfill('0') << guid.Data2;
os << '-';
os << std::hex << std::setw(4) << std::setfill('0') << guid.Data3;
os << '-';
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[0]);
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[1]);
os << '-';
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[2]);
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[3]);
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[4]);
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[5]);
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[6]);
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[7]);
std::string s(os.str());
std::cout << s << std::endl;
}
Alternatively, you could use sprintf_s for the string conversion
GUID guid;
CoCreateGuid(&guid);
char guidStr[37];
sprintf_s(
guidStr,
"%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX",
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
std::string s(guidStr);
To get in guid in std::string on Windows
#include <Windows.h>
#include <array>
std::string getGUID()
{
std::string result{};
GUID guid;
if (S_OK == CoCreateGuid(&guid))
{
std::array<char, 36> buffer{}; //32 characters of guid + 4 '-' in-between
snprintf(buffer.data(), buffer.size(), "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
result = std::string(buffer.data());
}
return result;
}
In the new WinRT api you can use winrt::Windows::Foundation::GuidHelper::CreateNewGuid() which returns a struct of winrt::guid type. You can later pass it to winrt::to_hstring to get struct of winrt::hstring type, then pass it to winrt::to_string to get std::string type.
Related
I have written a function MakeHashKeyFromFileKey16_FIRST() which works fine. Then I replaced Context_ws in line 6 of MakeHashKeyFromFileKey16_SECOND(). Suddenly my code does not work correctly.
Can anybody give me a hint as to why that is?
typedef wchar_t KMX_WCHART;
typedef uint16_t* PKMX_WCHAR ;
std::wstring MakeHashKeyFromFileKey16_FIRST(PFILE_KEY kp) {
std::wstringstream Key_16;
std::wstring Context_ws = u16fmt((const PKMX_WCHAR) kp->dpContext);
Key_16 << conv_KMX_WCHAR__TO__WCHAR(kp->Key) << "," << (DWORD) kp->ShiftFlags << ",";
if ((KMX_WCHART*) Context_ws.c_str()) Key_16 << (KMX_WCHART*) Context_ws.c_str();
return Key_16.str();
};
std::wstring MakeHashKeyFromFileKey16_SECOND(PFILE_KEY kp) {
std::wstringstream Key_16;
std::wstring Context_ws = u16fmt((const PKMX_WCHAR) kp->dpContext);
Key_16 << conv_KMX_WCHAR__TO__WCHAR(kp->Key) << "," << (DWORD) kp->ShiftFlags << ",";
if ((KMX_WCHART*) u16fmt((const PKMX_WCHAR) kp->dpContext).c_str()) Key_16 << (KMX_WCHART*) u16fmt((const PKMX_WCHAR) kp->dpContext).c_str();
return Key_16.str();
};
This may turn out to be a really easy question, but made very difficult by me not having used C++ in serious anger for a long time - my skills are rustier than an 80's Fiat!
I have a number of header files that define register addresses as #defines that have been provided to me.
I want to create a .dll that allows me to lookup these values via their name and returns their value as an unsigned long from another dev environment i.e.
#define A_REGISTER_ADDRESS 0x40
unsigned long myLookupFunction( string lookup )
{
// return value of #define specified by lookup as unsigned long
}
Thanks in advance for any help.
Dave
You could use a technique like this. This uses a macro generator to produce a std::map from the string name to the value and an enum with the same names and values.
#include <map>
#include <iostream>
#include <string>
#define ADDRESS(apply) \
apply(PORT1,0x40UL) \
apply(PORT2,0x42UL) \
apply(PORT3,0x43UL)
#define CREATE_MAP(name,value) \
{#name,value},
std::map<std::string, unsigned long> myMap = {ADDRESS(CREATE_MAP)};
#define CREATE_ENUM(name, value) \
name = value,
enum RegisterAddresses
{
ADDRESS(CREATE_ENUM)
};
unsigned long myLookupFunction(std::string lookup)
{
return myMap[lookup];
}
int main()
{
std::cout << "port PORT1 value " << std::hex << myLookupFunction("PORT1") << "\n";
std::cout << "port PORT2 value " << std::hex << myLookupFunction("PORT2") << "\n";
std::cout << "port PORT3 value " << std::hex << myLookupFunction("PORT3") << "\n";
std::cout << "port PORT1 enum value " << std::hex << PORT1 << "\n";
}
I currently have a log process in boost
that is initialized with
keywords::file_name = (my_file_str + %Y-%m-%d_%H.%5N.log).c_str();
Is there any way to change the timezone of the datetime object? I would like to use a timezone that rolls at 5PM US/New_York namely EST-2EDT.
Yes, it is possible, here is a function generating a timestamp in US/NY:
#include <boost/date_time/local_time/local_time.hpp>
#include <sstream>
std::string getNYCTimestamp() {
boost::posix_time::ptime pt =
boost::posix_time::microsec_clock::universal_time();
boost::local_time::time_zone_ptr utc_zone(
new boost::local_time::posix_time_zone("UTC"));
boost::local_time::local_date_time utc_time(pt, utc_zone);
boost::local_time::time_zone_ptr nyc_zone(
new boost::local_time::posix_time_zone("EST-05:00:00EDT+01:00:00,M4.1.0/02:00:00,M10.5.0/02:00:00"));
boost::local_time::local_date_time nyc_time = utc_time.local_time_in(nyc_zone);
auto our_facet = new boost::gregorian::date_facet("%Y-%m-%d");
our_facet->format("%Y-%m-%d");
auto os = std::ostringstream();
os.imbue(std::locale(std::locale::classic(), our_facet));
boost::posix_time::time_duration t = nyc_time.time_of_day();
os << nyc_time.date() << "_"
<< std::setw(2) << std::setfill('0') << t.hours() << '-'
<< std::setw(2) << std::setfill('0') << t.minutes() << '-'
<< std::setw(2) << std::setfill('0') << t.seconds() << '.'
<< std::setw(6) << std::setfill('0') << t.fractional_seconds();
return os.str();
}
Note, that "%Y-%m-%d_%H.%5N" is most probably wrong, because:
it omits minutes and seconds
it tries to fit nanoseconds (9 digits) into 5 symbols.
I am not 100% sure this will suffice (since I don't know what your requirements are) but here : http://boost-log.sourceforge.net/libs/log/doc/html/log/tutorial/attributes.html is a discussion of log attributes. It seems to me that you may be able to add it a secondary timestamp that is adjusted fo timezone.
I would like to print a bunch of integers on 2 fields with '0' as fill character. I can do it but it leads to code duplication. How should I change the code so that the code duplication can be factored out?
#include <ctime>
#include <sstream>
#include <iomanip>
#include <iostream>
using namespace std;
string timestamp() {
time_t now = time(0);
tm t = *localtime(&now);
ostringstream ss;
t.tm_mday = 9; // cheat a little to test it
t.tm_hour = 8;
ss << (t.tm_year+1900)
<< setw(2) << setfill('0') << (t.tm_mon+1) // Code duplication
<< setw(2) << setfill('0') << t.tm_mday
<< setw(2) << setfill('0') << t.tm_hour
<< setw(2) << setfill('0') << t.tm_min
<< setw(2) << setfill('0') << t.tm_sec;
return ss.str();
}
int main() {
cout << timestamp() << endl;
return 0;
}
I have tried
std::ostream& operator<<(std::ostream& s, int i) {
return s << std::setw(2) << std::setfill('0') << i;
}
but it did not work, the operator<< calls are ambigous.
EDIT I got 4 awesome answers and I picked the one that is perhaps the simplest and the most generic one (that is, doesn't assume that we are dealing with timestamps). For the actual problem, I will probably use std::put_time or strftime though.
In C++20 you'll be able to do this with std::format in a less verbose way:
ss << std::format("{}{:02}{:02}{:02}{:02}{:02}",
t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
t.tm_hour, t.tm_min, t.tm_sec);
and it's even easier with the {fmt} library that supports tm formatting directly:
auto s = fmt::format("{:%Y%m%d%H%M%S}", t);
You need a proxy for your string stream like this:
struct stream{
std::ostringstream ss;
stream& operator<<(int i){
ss << std::setw(2) << std::setfill('0') << i;
return *this; // See Note below
}
};
Then your formatting code will just be this:
stream ss;
ss << (t.tm_year+1900)
<< (t.tm_mon+1)
<< t.tm_mday
<< t.tm_hour
<< t.tm_min
<< t.tm_sec;
return ss.ss.str();
ps. Note the general format of my stream::operator<<() which does its work first, then returns something.
The "obvious" solution is to use a manipulator to install a custom std::num_put<char> facet which just formats ints as desired.
The above statement may be a bit cryptic although it entirely describes the solution. Below is the code to actually implement the logic. The first ingredient is a special std::num_put<char> facet which is just a class derived from std::num_put<char> and overriding one of its virtual functions. The used facet is a filtering facet which looks at a flag stored with the stream (using iword()) to determine whether it should change the behavior or not. Here is the code:
class num_put
: public std::num_put<char>
{
std::locale loc_;
static int index() {
static int rc(std::ios_base::xalloc());
return rc;
}
friend std::ostream& twodigits(std::ostream&);
friend std::ostream& notwodigits(std::ostream&);
public:
num_put(std::locale loc): loc_(loc) {}
iter_type do_put(iter_type to, std::ios_base& fmt,
char fill, long value) const {
if (fmt.iword(index())) {
fmt.width(2);
return std::use_facet<std::num_put<char> >(this->loc_)
.put(to, fmt, '0', value);
}
else {
return std::use_facet<std::num_put<char> >(this->loc_)
.put(to, fmt, fill, value);
}
}
};
The main part is the do_put() member function which decides how the value needs to be formatted: If the flag in fmt.iword(index()) is non-zero, it sets the width to 2 and calls the formatting function with a fill character of 0. The width is going to be reset anyway and the fill character doesn't get stored with the stream, i.e., there is no need for any clean-up.
Normally, the code would probably live in a separate translation unit and it wouldn't be declared in a header. The only functions really declared in a header would be twodigits() and notwodigits() which are made friends in this case to provide access to the index() member function. The index() member function just allocates an index usable with std::ios_base::iword() when called the time and it then just returns this index. The manipulators twodigits() and notwodigits() primarily set this index. If the num_put facet isn't installed for the stream twodigits() also installs the facet:
std::ostream& twodigits(std::ostream& out)
{
if (!dynamic_cast<num_put const*>(
&std::use_facet<std::num_put<char> >(out.getloc()))) {
out.imbue(std::locale(out.getloc(), new num_put(out.getloc())));
}
out.iword(num_put::index()) = true;
return out;
}
std::ostream& notwodigits(std::ostream& out)
{
out.iword(num_put::index()) = false;
return out;
}
The twodigits() manipulator allocates the num_put facet using new num_put(out.getloc()). It doesn't require any clean-up because installing a facet in a std::locale object does the necessary clean-up. The original std::locale of the stream is accessed using out.getloc(). It is changed by the facet. In theory the notwodigits could restore the original std::locale instead of using a flag. However, imbue() can be a relatively expensive operation and using a flag should be a lot cheaper. Of course, if there are lots of similar formatting flags, things may become different...
To demonstrate the use of the manipulators there is a simple test program below. It sets up the formatting flag twodigits twice to verify that facet is only created once (it would be a bit silly to create a chain of std::locales to pass through the formatting:
int main()
{
std::cout << "some-int='" << 1 << "' "
<< twodigits << '\n'
<< "two-digits1='" << 1 << "' "
<< "two-digits2='" << 2 << "' "
<< "two-digits3='" << 3 << "' "
<< notwodigits << '\n'
<< "some-int='" << 1 << "' "
<< twodigits << '\n'
<< "two-digits4='" << 4 << "' "
<< '\n';
}
Besides formatting integers with std::setw / std::setfill or ios_base::width / basic_ios::fill, if you want to format a date/time object you may want to consider using std::put_time / std::gettime
For convenient output formatting you may use boost::format() with sprintf-like formatting options:
#include <boost/format.hpp>
#include <iostream>
int main() {
int i1 = 1, i2 = 10, i3 = 100;
std::cout << boost::format("%03i %03i %03i\n") % i1 % i2 % i3;
// output is: 001 010 100
}
Little code duplication, additional implementation effort is marginal.
If all you want to do is output formatting of your timestamp, you should obviously use strftime(). That's what it's made for:
#include <ctime>
#include <iostream>
std::string timestamp() {
char buf[20];
const char fmt[] = "%Y%m%d%H%M%S";
time_t now = time(0);
strftime(buf, sizeof(buf), fmt, localtime(&now));
return buf;
}
int main() {
std::cout << timestamp() << std::endl;
}
operator<<(std::ostream& s, int i) is "ambiguous" because such a function already exists.
All you need to do is give that function a signature that doesn't conflict.
I'm looking for a very specific piece of information. I could make this a rather detailed question I guess but I'd rather try keeping it short and to the point.
I need to acces a piece of meta data (exif information) from within a Photoshop filter plug-in. I have never dealt with exif data from within a Photoshop plug-in or without and the PS SDK documentation is of a form that leaves a lot of questions. I would eventually get there but was wondering if anyone here has done this before and could help me out with an example. I'd be very grateful for that...
What we need should be documented here in the SDK:
documentation/html/group___resource_suite.html
documentation/html/imageresourcessection.html
The latter document says that the resource ID I need to retrieve the exif data is 1059 (decimal) and that accessing Exif data is supported since PS 7.0 which is good. But the SDK has no information (that I found) as to what you get, pointer? pointer to what? They just tell you to look at the exif spec. So do I get a pointer to the RAW binary exif data and if so how to I extract a field from that.
The specifications for the Exif data are here:
http://exif.org/specifications.html
As an example I'd like to get at this exif field:
Tag Name Field Name Dec Hex Type Count
Image title ImageDescription 270 10E ASCII Any
EDIT: After a deeper research I've found the following (an excerpt from the documentation):
Document: Photoshop API Guide.
Argument: Callbacks.
The callback routines are organized into “suites” collections of
related routines which implement a particular functionality.
The suites are described by a pointer to a record containing:
a 2 byte version number for the suite,
a 2 byte count of the number of routines in the suite,
a series of function pointers for the callback routines.
You are interested in the Property suite.
Current version: 1; Adobe Photoshop: 5.0; Routines: 2.
Properties are identified by a signature and key, which form a pair to
identify the property of interest.
Adobe Photoshop’s signature is always '8BIM' (0x3842494D).
The EXIF property is controlled by The Japan Electronic Industry Development Association (JEIDA) and Electronic Industries Association of Japan (EIAJ) which merged in Novemeber of 2000. The EXIF specification can be downloaded from their web site at the following location.
http://it.jeita.or.jp/jhistory/document/standard/exif_eng/jeida49eng.htm
GetPropertyProc( )
MACPASCAL OSErr (*GetPropertyProc) (OSType signature, OSType key, int32 index, int32 * simpleProperty, Handle * complexProperty);
This routine allows you to get information about the document currently being processed.
property name: propEXIFData
id:EXIF
type:complex (modifiable)
description:Camera and device data.
To recap I'll write some juicy code:
GetPropertyProc getProperty = formatParamBlock->propertyProcs->getPropertyProc;
rc = getProperty(0x3842494D, propEXIFData, 0, &simpProp, &compProp);
if ( rc )
return;
GetPIHandleSizeProc getSize = formatParamBlock->handleProcs->getSizeProc;
int32 size = getSize(compProp);
if ( !size )
return;
LockPIHandleProc lock = formatParamBlock->handleProcs->lockProc;
uint8* exif = (uint8 *)lock(compProp, false);
if ( !exif )
return;
Here's is a code sample using the Exiv2 Library: http://www.exiv2.org/doc/exifprint_8cpp-example.html
// ***************************************************************** -*- C++ -*-
// exifprint.cpp, $Rev: 2286 $
// Sample program to print the Exif metadata of an image
#include <exiv2/exiv2.hpp>
#include <iostream>
#include <iomanip>
#include <cassert>
int main(int argc, char* const argv[])
try {
if (argc != 2) {
std::cout << "Usage: " << argv[0] << " file\n";
return 1;
}
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[1]);
assert(image.get() != 0);
image->readMetadata();
Exiv2::ExifData &exifData = image->exifData();
if (exifData.empty()) {
std::string error(argv[1]);
error += ": No Exif data found in the file";
throw Exiv2::Error(1, error);
}
Exiv2::ExifData::const_iterator end = exifData.end();
for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {
const char* tn = i->typeName();
std::cout << std::setw(44) << std::setfill(' ') << std::left
<< i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right
<< std::hex << i->tag() << " "
<< std::setw(9) << std::setfill(' ') << std::left
<< (tn ? tn : "Unknown") << " "
<< std::dec << std::setw(3)
<< std::setfill(' ') << std::right
<< i->count() << " "
<< std::dec << i->value()
<< "\n";
}
return 0;
}
//catch (std::exception& e) {
//catch (Exiv2::AnyError& e) {
catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e.what() << "'\n";
return -1;
}
I combined response vulkanino and ThdK. My method uses the function PIGetEXIFData declared in file PropertyUtils.h that returns a binary exif. Next, this exif decoded Exiv2 library
#include <PropertyUtils.h>
#include <PIProperties.h>
#include <exif.hpp>
void printExif() {
Handle handle;
checkSPErr(PIGetEXIFData(handle));
std::string ss;
checkSPErr(HandleToString(handle, ss));
Exiv2::ExifData exifData;
Exiv2::ExifParser::decode(exifData, reinterpret_cast<const Exiv2::byte*>(ss.data()), ss.size());
Exiv2::ExifData::const_iterator end = exifData.end();
for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {
const char* tn = i->typeName();
std::cout << std::setw(44) << std::setfill(' ') << std::left
<< i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right
<< std::hex << i->tag() << " "
<< std::setw(9) << std::setfill(' ') << std::left
<< (tn ? tn : "Unknown") << " "
<< std::dec << std::setw(3)
<< std::setfill(' ') << std::right
<< i->count() << " "
<< std::dec << i->value()
<< "\n";
}
}