I'm currently learning how to create a C++ library to be referenced in other projects, and I am running into an issue with a "Debug Assertion Failed" error: is_block_type_valid(header-> _block_use). I followed the walkthrough shown here: Create and use your own Dynamic Link Library. Oddly, I am getting the expected answer if I just ignore the error.
My DLL currently only has one function:
cpp:
int calculate_crc(std::string msg)
{
std::vector<std::string> msg_vector = [](std::string& msg1) {
std::string next;
std::vector<std::string> result;
// for each char in string
for (std::string::const_iterator it = msg1.begin(); it != msg1.end(); it++)
{
// if we hit a terminal char
if (*it == ' ')
{
if (!next.empty())
{
// add them to the result vector
result.push_back(next);
next.clear();
}
}
else
{
next += *it;
}
}
if (!next.empty())
{
result.push_back(next);
}
return result;
} (msg);
int crcReg = 0xFFFF;
// iterate through each element in msgVector
for (auto&& element : msg_vector)
{
// step 2: xor operation performed on byte of msg and CRC register
crcReg ^= [](std::string hex) {
std::map<char, int> map;
map['0'] = 0;
map['1'] = 1;
map['2'] = 2;
map['3'] = 3;
map['4'] = 4;
map['5'] = 5;
map['6'] = 6;
map['7'] = 7;
map['8'] = 8;
map['9'] = 9;
map['a'] = 10;
map['b'] = 11;
map['c'] = 12;
map['d'] = 13;
map['e'] = 14;
map['f'] = 15;
return map[hex[1]] + (map[hex[0]] * 16);
} (element);
// step 3-5 are repeated until 8 bit shifts
for (int i = 0; i < 8; i++)
{
int crcCopy = crcReg;
crcReg >>= 1;
if ((crcCopy & 1) == 0)
continue;
else
crcReg ^= 0xA001;
}
}
return crcReg;
}
h:
#pragma once
#ifdef OMRONLIBRARY_EXPORTS
#define OMRONLIBRARY_API __declspec(dllexport)
#else
#define OMRONLIBRARY_API __declspec(dllimport)
#endif
#include <iostream>
extern "C" OMRONLIBRARY_API int calculate_crc(const std::string msg);
std::string is not a safe type to use in a DLL function parameter. Non-POD types should never be passed over a DLL boundary, unless they are type-erased (such as by using a void* pointer) and are only ever accessed directly by code on one side of the boundary and not the other side.
Assuming the caller is even using C++ at all (C-style DLLs can be used in non-C/C++ languages), it may be using a different std::string implementation. Or it may be using a different C++ compiler, or a different version of the same C++ compiler, or even just different settings for alignment, optimizations, etc. And even if all of that matches the DLL, it will likely be using a different instance of the memory manager that the DLL uses for its std::string implementation.
If you want to pass a string to a DLL function safely, use a C-style char* string instead. You can use std::string inside the DLL, if you want to, eg:
int calculate_crc(const char* msg)
{
use msg as-is ...
or
std::string s_msg = msg;
use s_msg as needed ...
}
extern "C" OMRONLIBRARY_API int calculate_crc(const char* msg);
Related
const char * u8_to_bstr(const uint8_t & u8) {
static char s[9]; // space for 8-char string
s[8] = 0; // terminate string
char * sp = s;
for (uint8_t xbit = 0b10000000; xbit > 0; xbit >>= 1) {
cout << s << endl;
*(sp++) = ((u8 & xbit) == xbit) ? '1' : '0';
}
return s;
}
I encountered this piece of code studying that converts a uint8 to a string representing its binary. My question is, why do we need the static qualifier for static char s[9]? When I remove the static qualifier I get some very strange behavior but I don't understand why.
The function returns s, which is declared on the stack of this function. Were it not static, it would go out of scope, effectively disappear, once the function returns because all the storage on the stack is made available for reuse once a function returns. By making it static, it’s forced to have a persistent address in memory. However, it’s still bad design - if you call this function from multiple threads, they’ll fight with each other for use of the static memory space.
To expand on what #VorpalSword offered in their answer, it doesn't have to be static. Instead you could dynamically allocate the array. This dynamically allocated memory will remain valid after u8_to_bstr exits.
const char * u8_to_bstr(const uint8_t & u8) {
const char *s = new char[9]; // space for 8-char string
s[8] = 0; // terminate string
char *sp = s;
for (uint8_t xbit = 0b10000000; xbit > 0; xbit >>= 1) {
cout << s << endl;
*(sp++) = ((u8 & xbit) == xbit) ? '1' : '0';
}
return s;
}
It's a remarkably small change to your code, but it does have implications for how your program works, and you do have to remember later to free up this memory.
delete[] variable_holding_results_of_u8_to_bstr;
This is a simple view os storing your data in memory so that it will remain usable after u8_to_bstr finishes its work without using static. It is by no means the only way or the best way.
In good practice, you'd make use of std::unique_ptr and std::vector rather than manually allocating and deleting arrays. Here is a quick view of your code translated to use these tools. Please note I've added a print_vec helper function.
#include <iostream>
#include <vector>
#include <memory>
using std::vector;
using std::unique_ptr;
using std::make_unique;
void print_vec(unique_ptr<vector<char>> const& v);
unique_ptr<vector<char>> u8_to_bstr(const uint8_t & u8);
int main() {
auto r = u8_to_bstr(45);
print_vec(r);
}
void print_vec(unique_ptr<vector<char>> const& v) {
for (auto ch : *v) {
std::cout << ch;
}
std::cout << std::endl;
}
unique_ptr<vector<char>> u8_to_bstr(const uint8_t & u8) {
auto s = make_unique<vector<char>>(9, '\0');
auto sp = s->begin();
for (uint8_t xbit = 0b10000000; xbit > 0; xbit >>= 1) {
print_vec(s);
*(sp++) = ((u8 & xbit) == xbit) ? '1' : '0';
}
return s;
}
You will almost certainly need to compile this specifying the C++14 or C++17 standards. If you wish to research the types and functions introduced, cppreference.com is a good site, and will tell you what C++ standards types/fucntions were introduced in.
I have a strange issue. I allocate char[] values in struct array, but they get lost:
------- The struct is this one :
typedef struct _Settings
{
const char* str;
uint val;
}Settings;
------- I create it like this :
int nn=10;
settings = new Settings[nn];
for (int i = 0; i < nn; i++) {
string strr = "thisOneIs";
strr.append(std::to_string(i));
settings[i].str = strr.c_str();
string teststr = settings[i].str; //// (1)
settings[i].val = i + 1;
}
..... at (1), I get the correct values.
But if I then call this (same place, right after the code above), the settings[i].str is empty:
for (int i = 0; i < nn; i++) {
string teststr = settings[i].str; ///// (2)
std::cout << settings[i].str << "=" << settings[i].val << "\n";
}
... at (2), I get empty.
Does anyone have a clue why? Thanks!
The line at (1) is a problem because you are storing a pointer to some memory that is not valid when the loop ends.
string strr = "thisOneIs"; // A temporary object in the loop.
strr.append(std::to_string(i));
settings[i].str = strr.c_str(); // Pointer that won't be valid when the loop ends.
If you learning about low level language features, it's ok to experiment with using char* and raw memory. If you are trying to get a working program, just use std::string.
Also simplify the definition of Settings. You don't need all the typedef non-sense in C++.
struct Settings
{
std::string str;
uint val;
};
Let's say we have a string
"{GUID}"
wherein GUID is a standard GUID in {}. I need to get a variable of type GUID matching the given string. It is to be done with visual C++ and the version is very old (6.0) if that matters.
Firstly I tried to use GUIDFromString function but wasn't able to get it imported so found out about UuidFromString. But I am really stuck at all these casts from unsigned char to char etc, having no C++ background it is very hard. Maybe some one will be so kind to help me with this. Thanks.
GUID refers to some unique identification number, which can be generated using some algorithm - you can find some descriptions on Microsoft's algorithms - where they try to pick up timestamp, network card number, and on one, and mix up into one unique GUID.
What I have checked - noone prevents you of creating your own "unique" generation algorithm - but you need to somehow ensure that your unique generation algorithm won't collide with existing algorithms, which is highly unlikely. Also GUID's generated by your algorithm should not also collide with your own GUID's.
While browsing internet I have found some approaches to generate such guid - for example - Microsoft Office: http://support.microsoft.com/kb/2186281
When generating GUID from Strings, you can use either String.GetHashCode32 or even calculate for example 20 byte sha-1 hash over string. (First one is easier, but second creates more bytes to use for GUID).
And then start to fill in GUID, as much as it requires it.
Here is some demo code which let's you get to the idea:
using System;
class Program
{
/// <summary>
/// http://stackoverflow.com/questions/53086/can-i-depend-on-the-values-of-gethashcode-to-be-consistent
///
/// Similar to String.GetHashCode but returns the same as the x86 version of String.GetHashCode for x64 and x86 frameworks.
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static unsafe int GetHashCode32(string s)
{
fixed (char* str = s.ToCharArray())
{
char* chPtr = str;
int num = 0x15051505;
int num2 = num;
int* numPtr = (int*)chPtr;
for (int i = s.Length; i > 0; i -= 4)
{
num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
if (i <= 2)
{
break;
}
num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
numPtr += 2;
}
return (num + (num2 * 0x5d588b65));
}
}
/// <summary>
/// Generates new product code for particular product / install package.
/// </summary>
/// <param name="productName">Logical product name for which to generate</param>
/// <param name="productVersion">Product version in form "1.0.0"</param>
/// <returns></returns>
static public String GenerateProductCode( String productName, String productVersion )
{
String[] vparts = productVersion.Split(".".ToCharArray());
int[] verParts = new int [3] { 1, 0, 0 };
int i = 0;
foreach( String v in vparts )
{
Int32.TryParse(v, out verParts[i++] );
if( i >= 3 ) break;
}
//
// "MyCompanyName", "1.0.2" will generate guid like this: {F974DC1F-0001-0000-0002-10009CD45A98}
// ^ Hash over manufacturer name - "MyCompanyName"
// ^ Version - "<major>-<minor>-<build>" in hexadecimal
// ^ 1 as for 64 bit.
// ^000 - just reserved for future needs
// ^ Hash over product name
//
// See also similar generation schemes - http://support.microsoft.com/kb/2186281.
//
String newGuid = String.Format("{0:X8}-{1:X4}-{2:X4}-{3:X4}-1000{4:X8}", GetHashCode32("MyCompanyName"), verParts[0], verParts[1], verParts[2], GetHashCode32(productName));
newGuid = "{" + newGuid + "}";
return newGuid;
}
static void Main()
{
String s = GenerateProductCode("MyProduct", "1.0.2");
Console.WriteLine(s);
}
}
Will print out:
{F974DC1F-0001-0000-0002-10003618D1E1}
But in similar manner you can generate GUIDs in C++ as well - use sprintf() most probably.
Here is .NET compatible function for converting String into hash code:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int GetHashCode32( const wchar_t* ps )
{
int num = 0x15051505;
int num2 = num;
const wchar_t* s = ps;
const char* chPtr=(const char*) ps;
size_t numBuff = wcslen((wchar_t*) chPtr) * 2;
int* numPtr = (int*)chPtr;
for (int i = wcslen(s); i > 0; i -= 4)
{
num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
if (i <= 2)
{
break;
}
num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
numPtr += 2;
}
return (num + (num2 * 0x5d588b65));
}
void GetHash(const wchar_t* p)
{
printf("'%S' = %08X", p, GetHashCode32(p));
printf("\r\n");
}
void main(void)
{
GetHash(L"testing");
GetHash(L"MainClass::" __FUNCTIONW__);
GetHash(L"1");
GetHash(L"");
}
Okay, the problem was in include and libs. You need to include <Rpc.h> and link the RPC library:
#pragma comment (lib, "Rpcrt4.lib")
And than you can use UuidFromString function. Just note that you don't need to include { and } in your string representation.
Is there some function like GCC's __builtin_constant_p() for Microsoft Visual Studio? As I understand, the function returns non-zero if the argument is constant, like a string literal.
In the answer here (How to have "constexpr and runtime" alias) is a nice use case of it.
EDIT:
My idea was instead of writing something like:
#include <string.h>
int foo() {
return strlen("text");
}
I could write:
#include <string.h>
// template_strlen() would be a function that gets the length of a compile-time const string via templates
#define STRLEN(a) (__builtin_constant_p(a) ? template_strlen(a) : strlen(a))
int foo() {
return STRLEN("text");
}
(I guess that is about what was written in the linked question.)
All I need for that is a variant of __builtin_constant_p().
Here is an example about how to get compile-time detection of string length (which is not the answer to the initial question but to the second one)
Please notice however that most compiler already replace strlen("bob") by 3 in the very first optimization level, so I doubt it has any use in reality.
template <typename T>
struct StrLenHelper
{
static constexpr size_t len(T) { return 0; }
};
template <size_t sel>
struct StrLenHelper<const char (&)[sel]>
{
static constexpr size_t len(const char (&a)[sel]) { return sel-1; }
};
template <>
struct StrLenHelper<const char*>
{
static size_t len(const char * a) { return strlen(a); }
};
#define StrLen(X) StrLenHelper<decltype(X)>::len(X)
Proof that it works on a recent compiler:
template <size_t A>
struct Test { enum T { value = A }; };
// Outputs "5 5 4" if your program is called "test"
int main(int a, char**b)
{
printf("%u %u %u\n", Test<StrLen("bobby")>::value, StrLen("bobby"), StrLen(b[0]));
return 0;
}
Some strange coding practice will not trigger compile-time behaviour like in constexpr const char * b = "bob";, this will call the run-time version because the type, at the time of call is const char* (constexpr is not a modifier you can select upon in a template, or I don't know how)
In Visual Studio 2012 and Visual Studio 2013 there is the _IS_LITERAL_TYPE macro which makes use of std::is_literal_type, which is documented at http://www.cplusplus.com/reference/type_traits/is_literal_type/.
The following is a relevant excerpt from the documentation of is_literal_type.
"""Trait class that identifies whether T is a literal type.
A literal type is a type that can qualify as constexpr."""
Perhaps this would suffice.
The following excerpt from the documentation for __builtin_constant_p leads me to believe it will.
"You can use the built-in function __builtin_constant_p to determine if a value is known to be constant at compile-time..."
To me the phrases "is a literal type," "constexpr," and "known to be constant at compile-time" have the same meaning. Perhaps I am mistaken.
Then again, I will be the first to admit that I am not certain.
If is_literal_type is not what you want, the following function might be of use. With it I was able to tell the difference between a char string that was defined as follows and one that was allocated on the heap.
LPCTSTR constString = _T("Hello World!");
My implementation of constant_p is as follows.
int constant_p(const void *p)
{
static bool s_init = false;
static ULONGLONG s_TextSegmentStartVirtualAddress = 0;
static ULONGLONG s_TextSegmentEndVirtualAddress = 0;
static ULONGLONG s_RDataSegmentStartVirtualAddress = 0;
static ULONGLONG s_RDataSegmentEndVirtualAddress = 0;
if (! s_init)
{
s_init = true;
PIMAGE_NT_HEADERS pNtHeaders = ::ImageNtHeader(
reinterpret_cast<PVOID>(::GetModuleHandle(NULL)));
if (! pNtHeaders)
{
return 0;
}
ULONGLONG ImageBase = pNtHeaders->OptionalHeader.ImageBase;
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)(pNtHeaders + 1);
for (WORD i = 0; i < pNtHeaders->FileHeader.NumberOfSections; ++i)
{
char *name = (char*)pSectionHeader->Name;
if (0 == ::strcmp(name, ".text"))
{
s_TextSegmentStartVirtualAddress = ImageBase
+ pSectionHeader->VirtualAddress;
s_TextSegmentEndVirtualAddress = s_TextSegmentStartVirtualAddress
+ pSectionHeader->SizeOfRawData;
}
else if (0 == ::strcmp(name, ".rdata"))
{
s_RDataSegmentStartVirtualAddress = ImageBase
+ pSectionHeader->VirtualAddress;
s_RDataSegmentEndVirtualAddress = s_RDataSegmentStartVirtualAddress
+ pSectionHeader->SizeOfRawData;
}
pSectionHeader++;
}
}
if (0 == s_TextSegmentStartVirtualAddress)
{
// Something went wrong. Give up.
return 0;
}
ULONGLONG test = reinterpret_cast<ULONGLONG>(p);
if (
s_TextSegmentStartVirtualAddress <= test
&& test <= s_TextSegmentEndVirtualAddress
)
{
return 1;
}
else if (
s_RDataSegmentStartVirtualAddress <= test
&& test <= s_RDataSegmentEndVirtualAddress
)
{
return 1;
}
return 0;
}
Note you need to include DbgHelp.h and link with DbgHelp.lib in order for this to work.
I hope one of my proposed solutions works for you. I would like to know.
I have an instance of CXCursor of kind CXCursor_CXXMethod. I want to find out if the function is const or volatile, for example:
class Foo {
public:
void bar() const;
void baz() volatile;
void qux() const volatile;
};
I could not find anything useful in the documentation of libclang. I tried clang_isConstQualifiedType and clang_isVolatileQualifiedType but these always seem to return 0 on C++ member function types.
I can think of two approaches:
Using the libclang lexer
The code which appears in this SO answer works for me; it uses the libclang tokenizer to break a method declaration apart, and then records any keywords outside of the method parentheses.
It does not access the AST of the code, and as far as I can tell doesn't involve the parser at all. If you are sure the code you investigate is proper C++, I believe this approach is safe.
Disadvantages: This solution does not appear to take into account preprocessing directives, so the code has to be processed first (e.g., passed through cpp).
Example code (the file to parse must be the first argument to your program, e.g. ./a.out bla.cpp):
#include "clang-c/Index.h"
#include <string>
#include <set>
#include <iostream>
std::string GetClangString(CXString str)
{
const char* tmp = clang_getCString(str);
if (tmp == NULL) {
return "";
} else {
std::string translated = std::string(tmp);
clang_disposeString(str);
return translated;
}
}
void GetMethodQualifiers(CXTranslationUnit translationUnit,
std::set<std::string>& qualifiers,
CXCursor cursor) {
qualifiers.clear();
CXSourceRange range = clang_getCursorExtent(cursor);
CXToken* tokens;
unsigned int numTokens;
clang_tokenize(translationUnit, range, &tokens, &numTokens);
bool insideBrackets = false;
for (unsigned int i = 0; i < numTokens; i++) {
std::string token = GetClangString(clang_getTokenSpelling(translationUnit, tokens[i]));
if (token == "(") {
insideBrackets = true;
} else if (token == "{" || token == ";") {
break;
} else if (token == ")") {
insideBrackets = false;
} else if (clang_getTokenKind(tokens[i]) == CXToken_Keyword &&
!insideBrackets) {
qualifiers.insert(token);
}
}
clang_disposeTokens(translationUnit, tokens, numTokens);
}
int main(int argc, char *argv[]) {
CXIndex Index = clang_createIndex(0, 0);
CXTranslationUnit TU = clang_parseTranslationUnit(Index, 0,
argv, argc, 0, 0, CXTranslationUnit_None);
// Set the file you're interested in, and the code location:
CXFile file = clang_getFile(TU, argv[1]);
int line = 5;
int column = 6;
CXSourceLocation location = clang_getLocation(TU, file, line, column);
CXCursor cursor = clang_getCursor(TU, location);
std::set<std::string> qualifiers;
GetMethodQualifiers(TU, qualifiers, cursor);
for (std::set<std::string>::const_iterator i = qualifiers.begin(); i != qualifiers.end(); ++i) {
std::cout << *i << std::endl;
}
clang_disposeTranslationUnit(TU);
clang_disposeIndex(Index);
return 0;
}
Using libclang's Unified Symbol Resolution (USR)
This approach involves using the parser itself, and extracting qualifier information from the AST.
Advantages: Seems to work for code with preprocessor directives, at least for simple cases.
Disadvantages: My solution parses the USR, which is undocumented, and might change in the future. Still, it's easy to write a unit-test to guard against that.
Take a look at $(CLANG_SRC)/tools/libclang/CIndexUSRs.cpp, it contains the code that generates a USR, and therefore contains the information required to parse the USR string. Specifically, lines 523-529 (in LLVM 3.1's source downloaded from www.llvm.org) for the qualifier part.
Add the following function somewhere:
void parseUsrString(const std::string& usrString, bool* isVolatile, bool* isConst, bool *isRestrict) {
size_t bangLocation = usrString.find("#");
if (bangLocation == std::string::npos || bangLocation == usrString.length() - 1) {
*isVolatile = *isConst = *isRestrict = false;
return;
}
bangLocation++;
int x = usrString[bangLocation];
*isConst = x & 0x1;
*isVolatile = x & 0x4;
*isRestrict = x & 0x2;
}
and in main(),
CXString usr = clang_getCursorUSR(cursor);
const char *usr_string = clang_getCString(usr);
std::cout << usr_string << "\n";
bool isVolatile, isConst, isRestrict;
parseUsrString(usr_string, &isVolatile, &isConst, &isRestrict);
printf("restrict, volatile, const: %d %d %d\n", isRestrict, isVolatile, isConst);
clang_disposeString(usr);
Running on Foo::qux() from
#define BLA const
class Foo {
public:
void bar() const;
void baz() volatile;
void qux() BLA volatile;
};
produces the expected result of
c:#C#Foo#F#qux#5
restrict, volatile, const: 0 1 1
Caveat: you might have noticed that libclang's source suggets my code should be isVolatile = x & 0x2 and not 0x4, so it might be the case you should replace 0x4 with 0x2. It's possible my implementation (OS X) has them replaced.