Transferring string arrays from VBA7 to C++ - c++

I'm currently working on a project where I want to be able to manipulate and graph data with relative ease in Excel. However, a lot of the data involved exceeds Excels row limits considerably and it needs a degree of preprocessing before I can work with it.
To solve this I decided to write a backend in C++ to handle the preprocessing so that it's acceptable for Excel. The aim is to be able to pick several files within excel which are then sent to the .dll to be parsed, preprocessed, and have some averaging applied to make it more easily handled in excel. The data is then passed back to Excel to be graphed, etc.
I've already worked out how to send arrays of data from the .dll to Excel reliably. However, sending data from Excel to the .dll, usually an array of BSTR which hold file paths, has proven more difficult.
After reading through a few questions:
How to create an array of strings in VBA/Excel and send it to a C++ DLL so that it can be iterated through in the DLL
VBA/Excel, and C++ DLL, specifically problems with strings
Calling C++ function from Excel and VBA using DLL created in C++
I thought the following code should work:
// lib.cpp
/*
* clear_log() & write_log(...) both write to a specified log file
*/
inline std::string WINAPI
bstr_string_convert( const BSTR bstr ) {
const auto bstrlen = SysStringLen(bstr);
const auto buffer = new char[bstrlen + 1];
size_t n_char_converted{ 0 };
if ( bstrlen > 0 ) {
const auto err =
wcstombs_s( &n_char_converted,
buffer, bstrlen + 1,
bstr, bstrlen );
}
else {
buffer[0] = '\0';
}
return std::string{ buffer };
}
const std::string log_location{
"C:\\\\path\\to\\log\\location\\"
};
void WINAPI
clear_log( const std::string_view filename ) {
std::fstream log_file( log_location + filename,
std::ios_base::out | std::ios_base::trunc );
log_file.close();
}
void WINAPI
write_log( const std::string_view filename, const std::string_view str ) {
std::fstream log_file( log_location + filename,
std::ios_base::out | std::ios_base::app );
log_file << str << "\n";
log_file.close();
}
// This works
__declspec(dllexport) LPSAFEARRAY WINAPI
get_double_array( _In_ const LPSAFEARRAY* ppsa ) {
CComSafeArray<double> csa(*ppsa);
clear_log("double_log.txt");
write_log( "double_log.txt",
std::format("size: {}", csa.GetCount()) );
for ( LONG i{ csa.GetLowerBound() }; i < csa.GetUpperBound(); ++i ) {
write_log( "double_log.txt",
std::format("{}: {}", i, csa.GetAt(i)) );
}
return csa.Detach();
}
// This doesn't
__declspec(dllexport) LPSAFEARRAY WINAPI
get_str_array( _In_ const LPSAFEARRAY* ppsa ) {
CComSafeArray<BSTR> csa(*ppsa);
clear_log("string_log.txt");
write_log( "string_log.txt",
std::format("size: {}", csa.GetCount()));
for (LONG i{ csa.GetLowerBound() }; i < csa.GetUpperBound(); ++i ) {
write_log( "string_log.txt",
std::format( "{}: {}",
i,
bstr_string_convert(csa.GetAt(i))
) );
}
return csa.Detach();
}
Declare PtrSafe Function send_string_array _
Lib "path\to\dll" _
Alias "_get_str_array#4" _
(ByRef first_element() As String) As String()
Declare PtrSafe Function send_double_array _
Lib "path\to\dll" _
Alias "_get_double_array#4" _
(ByRef ptr() As Double) As Double()
(Not sure what's making the syntax highlighting weird here)
Sub test()
Dim doubles(3) As Double
doubles(0) = 3.141592
doubles(1) = 1235.12617
doubles(2) = -1266.2346
Dim d_result() As Double
d_result = send_double_array(doubles)
Dim n As Long
For n = 0 To 2
Debug.Print d_result(n)
Next n
Dim strings(3) As String
strings(0) = "This"
strings(1) = "is a "
strings(2) = "test."
Dim result() As String
result = send_string_array(strings)
For n = 0 To 2
Debug.Print result(n)
Next n
End Sub
Immediate Window:
3.141592
1235.12617
-1266.2346
??
??
??
double_log.txt:
size: 4
0: 3.141592
1: 1235.12617
2: -1266.2346
string_log.txt:
size: 4
0:
1:
2:
So my question is what am I missing that causes get_double_array(...) to work, but get_str_array(...) doesn't?
As an aside, why does CComSafeArray::GetCount() return 4 for an array declared with 3 elements? Seems like something weird is going on there.

Related

C++, efficient way to call many possible functions from user

I'm relatively new to c++, mostly worked with python.
I have a scenario where a user(me) uses a GUI to send commands to a microcontroller via serial, and then the microcontroller processes them.
Right now i have 10 commands, but as the project develops (some form of modular robot) I can envision having 50-100 possible commands.
Is there a better way for my c++ handleCommands function to select which one of the possible 100 functions to run without doing massive case switches or if else statements?
Extract of the code:
char cmd = 1; // example place holder
int value = 10; //example place holder
switch (cmd){
case '1':
toggleBlink(value);
break;
case '2':
getID(value); // in this case value gets ignored by the function as its not required
break;
This works fine for 3-4 functions but doesn't seem to me like the best way to do it for more functions.
I've heard of lookup tables but as each function is different and may require arguments or not I'm consumed on how to implement them.
Some background on the set-up:
The commands are mainly diagnostic ,< ID > ect and a couple of functional ones that require parameters like, <blink,10> <runto,90> <set-mode,locked>
The validation is done in python against a csv file and the actual serial message sent to the microcontroller is sent as <(index of comand in csvfile),parameter> with < > and , being delimiters.
So the user would type blink,10 and the python app will send <1,10> over serial as blink is found at index 1 of the csv file.
The microcontroller reads these in and i am left over with 2 char arrays, the command array containing a number, and the value array containing the value sent.(also a number)
As I'm running this on a microcontroller i don't really want to have to store a long file of possible commands in flash, hence the validation done on the python gui side.
Note that in the case of a possible multi argument function, say <move,90,30> i.e move 90 degrees in 30 seconds eat, the actual function would only receive one argument "30,90" and then split that up as needed.
If you have the commands comming over the serial line in the format
<command-mapped-to-a-number,...comma-separated-parameters...>
we can simulate that like so:
#include <iostream>
#include <sstream> // needed for simple parsing
#include <string>
#include <unordered_map> // needed for mapping of commands to functors
int main() {
std::cout << std::boolalpha;
// example commands lines read from serial:
for (auto& cmdline : {"<1,10>", "<2,10,90>", "<3,locked>", "<4>"}) {
std::cout << exec(cmdline) << '\n';
}
}
exec above is the interpreter that will return true if the command line was parsed and executed ok. In the examples above, command 1 takes one parameter, 2 takes two, 3 takes one (string) and 4 doesn't have a parameter.
The mapping from command-mapped-to-a-number could be an enum:
// uint8_t has room for 256 commands, make it uint16_t to get room for 65536 commands
enum class command_t : uint8_t {
blink = 1,
take_two = 2,
set_mode = 3,
no_param = 4,
};
and exec would make the most basic validation of the command line (checking < and >) and put it in a std::istringstream for easy extraction of the information on this command line:
bool exec(const std::string& cmdline) {
if(cmdline.size() < 2 || cmdline.front() != '<' || cmdline.back() != '>' )
return false;
// put all but `<` and `>` in an istringstream:
std::istringstream is(cmdline.substr(1,cmdline.size()-2));
// extract the command number
if (int cmd; is >> cmd) {
// look-up the command number in an `unordered_map` that is mapped to a functor
// that takes a reference to an `istringstream` as an argument:
if (auto cit = commands.find(command_t(cmd)); cit != commands.end()) {
// call the correct functor with the rest of the command line
// so that it can extract, validate and use the arguments:
return cit->second(is);
}
return false; // command look-up failed
}
return false; // command number extraction failed
}
The only tricky part left is the unordered_map of commands and functors.
Here's a start:
// a helper to eat commas from the command line
struct comma_eater {} comma;
std::istream& operator>>(std::istream& is, const comma_eater&) {
// next character must be a comma or else the istream's failbit is set
if(is.peek() == ',') is.ignore();
else is.setstate(std::ios::failbit);
return is;
}
std::unordered_map<command_t, bool (*)(std::istringstream&)> commands{
{command_t::blink,
[](std::istringstream& is) {
if (int i; is >> comma >> i && is.eof()) {
std::cout << "<blink," << i << "> ";
return true;
}
return false;
}},
{command_t::take_two,
[](std::istringstream& is) {
if (int a, b; is >> comma >> a >> comma >> b && is.eof()) {
std::cout << "<take-two," << a << ',' << b << "> ";
return true;
}
return false;
}},
{command_t::set_mode,
[](std::istringstream& is) {
if (std::string mode; is >> comma && std::getline(is, mode,',') && is.eof()) {
std::cout << "<set-mode," << mode << "> ";
return true;
}
return false;
}},
{command_t::no_param,
[](std::istringstream& is) {
if (is.eof()) {
std::cout << "<no-param> ";
return true;
}
return false;
}},
};
If you put that together you'll get the below output from the successful parsing (and execution) of all command lines received:
<blink,10> true
<take-two,10,90> true
<set-mode,locked> true
<no-param> true
Here's a live demo.
Given an integer index for each "command" a simple function pointer look-up table can be used. For example:
#include <cstdio>
namespace
{
// Command functions (dummy examples)
int examleCmdFunctionNoArgs() ;
int examleCmdFunction1Arg( int arg1 ) ;
int examleCmdFunction2Args( int arg1, int arg2 ) ;
int examleCmdFunction3Args( int arg1, int arg2, arg3 ) ;
int examleCmdFunction4Args( int arg1, int arg2, int arg3, int arg4 ) ;
const int MAX_ARGS = 4 ;
const int MAX_CMD_LEN = 32 ;
typedef int (*tCmdFn)( int, int, int, int ) ;
// Symbol table
#define CMD( f ) reinterpret_cast<tCmdFn>(f)
static const tCmdFn cmd_lookup[] =
{
0, // Invalid command
CMD( examleCmdFunctionNoArgs ),
CMD( examleCmdFunction1Arg ),
CMD( examleCmdFunction2Args ),
CMD( examleCmdFunction3Args ),
CMD( examleCmdFunction4Args )
} ;
}
namespace cmd
{
// For commands of the form: "<cmd_index[,arg1[,arg2[,arg3[,arg4]]]]>"
// i.e an angle bracketed comma-delimited sequence commprising a command
// index followed by zero or morearguments.
// e.g.: "<1,123,456,0>"
int execute( const char* command )
{
int ret = 0 ;
int argv[MAX_ARGS] = {0} ;
int cmd_index = 0 ;
int tokens = std::sscanf( "<%d,%d,%d,%d,%d>", command, &cmd_index, &argv[0], &argv[1], &argv[2], &argv[3] ) ;
if( tokens > 0 && cmd_index < sizeof(cmd_lookup) / sizeof(*cmd_lookup) )
{
if( cmd_index > 0 )
{
ret = cmd_lookup[cmd_index]( argv[0], argv[1], argv[2], argv[3] ) ;
}
}
return ret ;
}
}
The command execution passes four arguments (you can expand that as necessary) but for command functions taking fewer arguments they will simply be "dummy" arguments that will be ignored.
Your proposed translation to an index is somewhat error prone and maintenance heavy since it requires you to maintain both the PC application symbol table and the embedded look up table in sync. It may not be prohibitive to have the symbol table on the embedded target; for example:
#include <cstdio>
#include <cstring>
namespace
{
// Command functions (dummy examples)
int examleCmdFunctionNoArgs() ;
int examleCmdFunction1Arg( int arg1 ) ;
int examleCmdFunction2Args( int arg1, int arg2 ) ;
int examleCmdFunction3Args( int arg1, int arg2, arg3 ) ;
int examleCmdFunction4Args( int arg1, int arg2, int arg3, int arg4 ) ;
const int MAX_ARGS = 4 ;
const int MAX_CMD_LEN = 32 ;
typedef int (*tCmdFn)( int, int, int, int ) ;
// Symbol table
#define SYM( c, f ) {#c, reinterpret_cast<tCmdFn>(f)}
static const struct
{
const char* symbol ;
const tCmdFn command ;
} symbol_table[] =
{
SYM( cmd0, examleCmdFunctionNoArgs ),
SYM( cmd1, examleCmdFunction1Arg ),
SYM( cmd2, examleCmdFunction2Args ),
SYM( cmd3, examleCmdFunction3Args ),
SYM( cmd4, examleCmdFunction4Args )
} ;
}
namespace cmd
{
// For commands of the form: "cmd[ arg1[, arg2[, arg3[, arg4]]]]"
// i.e a command string followed by zero or more comma-delimited arguments
// e.g.: "cmd3 123, 456, 0"
int execute( const char* command_line )
{
int ret = 0 ;
int argv[MAX_ARGS] = {0} ;
char cmd[MAX_CMD_LEN + 1] ;
int tokens = std::sscanf( "%s %d,%d,%d,%d", command_line, cmd, &argv[0], &argv[1], &argv[2], &argv[3] ) ;
if( tokens > 0 )
{
bool cmd_found = false ;
for( int i = 0;
!cmd_found && i < sizeof(symbol_table) / sizeof(*symbol_table);
i++ )
{
cmd_found = std::strcmp( cmd, symbol_table[i].symbol ) == 0 ;
if( cmd_found )
{
ret = symbol_table[i].command( argv[0], argv[1], argv[2], argv[3] ) ;
}
}
}
return ret ;
}
}
For very large symbol tables you might want a more sophisticated look-up, but depending on the required performance and determinism, the simple exhaustive search will be sufficient - far faster than the time taken to send the serial data.
Whilst the resource requirement for the symbol table is somewhat higher that the indexed look-up, it is nonetheless ROM-able and will can be be located in Flash memory which on most MCUs is a less scarce resource than SRAM. Being static const the linker/compiler will most likely place the tables in ROM without any specific directive - though you should check the link map or the toolchain documentation n this.
In both cases I have defined the command functions and executer as returning an int. That is optional of course, but you might use that for returning responses to the PC issuing the serial command.
What you are talking about are remote procedure calls. So you need to have some mechanism to serialize and un-serialize the calls.
As mentioned in the comments you can make a map from cmd to the function implementing the command. Or simply an array. But the problem remains that different functions will want different arguments.
So my suggestion would be to add a wrapper function using vardiac templates.
Prefix every command with the length of data for the command so the receiver can read a block of data for the command and knows when to dispatch it to a function. The wrapper then takes the block of data, splits it into the right size for each argument and converts it and then calls the read function.
Now you can make a map or array of those wrapper function, each one bound to one command and the compiler will generate the un-serialize code for you from the types. (You still have to do it once for each type, the compiler only combines those for the full function call).

C++ Dll function call crashes on return

_declspec(dllexport) void Send(string strEmailAddress, string strHostAddress, string strUserName, string strPswrd, string strLocalFile, string strServerLocation, string strErrorMessage )
{
nsFTP::CFTPClient ft ;
wstring wstrHostName ( strHostAddress.begin(),strHostAddress.end() );
string strApplicationUserName = "acpmat";
string strApplicationPswrd = "A1c2p.M3a4t";
wstring wstrUserName ( strApplicationUserName.begin(),strApplicationUserName.end() );
wstring wstrPwrd ( strApplicationPswrd.begin(),strApplicationPswrd.end() );
wstring wstrLocalFile( strLocalFile.begin(),strLocalFile.end() );
wstring wstrServerLoc( strServerLocation.begin(),strServerLocation.end() );
nsFTP::CLogonInfo logonInfo(wstrHostName, 21, wstrUserName, wstrPwrd);
// connect to server
ft.Login(logonInfo);
ft.UploadFile(wstrLocalFile, wstrServerLoc);
CArray<CString, LPCTSTR> xToEmails;
wstring strMailTo( strEmailAddress.begin(), strEmailAddress.end() );
xToEmails.Add(strMailTo.c_str());
const CString xCCEmail;
const CString xReplyTo;
const CString xSubject(strErrorMessage.c_str());
strUserName.append( " " );
strUserName.append( strLocalFile.c_str() );
const CString xBodyFilePath( strUserName.c_str() );
const CString& xFrom = _T("Exe_Crash#cat.com");
const CString& xAttachmentFilePath = _T("");
const CString& xServer = PES_EMAIL_SERVER;
int xPort = PES_EMAIL_PORT;
const CString& xCommand = PES_EMAIL_COMMAND;
int lRes = email::Send(xToEmails, xCCEmail, xReplyTo, xSubject, xBodyFilePath);
return true;
}
I call the above function from another application
typedef void (*FNPTR)(string a, string b, string c, string d, string e, string f, string g );
//typedef int (__cdecl *MYPROC)(LPWSTR);
HINSTANCE hinstLib;
//MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess;
hinstLib = LoadLibrary(TEXT("DllCrashReport.dll"));
if (hinstLib != NULL)
{
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
FNPTR fn = (FNPTR)GetProcAddress(hinstLib, "Send");
// If the function address is valid, call the function.
if (NULL != fn)
{
TCHAR name_1 [ UNLEN + 1 ];
DWORD size_1 = UNLEN + 1;
GetUserName( (TCHAR*)name_1, &size_1 );
strUserName.clear();
strUserName.append( name_1 );
//use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
std::string converted_str( strUserName.begin() , strUserName.end() );
fRunTimeLinkSuccess = TRUE;
fn( strEmailAddress, strHostAddress, converted_str, strPswrd, strLocalFile, strServerLocation, strMailErrorMessage );
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function
if (!fRunTimeLinkSuccess)
return ;
}
The call stack shows me this: Symbols loaded.
HEAP[MaterialCheck.exe]: Invalid address specified to RtlValidateHeap( 0000000000390000, 0000000002B82D30 ) and the crash occurs when it says that it tries to > mfc110ud.dll!operator delete(void * p) Line 351 C++
Can someone kindly help me please. THanks
!!!! This is an important finding .. The problem got solved and this was a new learning for me.
While passing strings as parameter into a dll function call from another application , please pass the parameters as "const char*" and not as native strings.
Kindly refer:
C++ Passing std::string by reference to function in dll

How do I cast a void pointer to a int[3]?

I need to call a 3rd party library and pass in an int[3] as a void * like this [works]:
int pattern[3] = {2,4,10};
if ( OSTaskCreate( BlinkLED,
( void * ) pattern,
( void * ) &BlinkTaskStack[USER_TASK_STK_SIZE],
( void * ) BlinkTaskStack,
MAIN_PRIO - 1 ) != OS_NO_ERR )
{
iprintf( "*** Error creating blink task\r\n" );
}
But now I need to parse a string to get the pattern array and I can't seem to get it right.
First I pass the string into the parser and get back the array:
int (&ParseBlinkOnCommand(char rxbuffer[3]))[3]
{
// Code parses rxbuffer and creates the 3 ints needed
int pattern[3] = {repeats, onTicks, offTicks};
return pattern;
}
Then I try to pass it to the OSTaskCreate just like I did before:
int pattern2[3] = ParseBlinkOnCommand(rxbuffer);
if ( OSTaskCreate( BlinkLED,
( void * ) pattern2,
( void * ) &BlinkTaskStack[USER_TASK_STK_SIZE],
( void * ) BlinkTaskStack,
MAIN_PRIO - 1 ) != OS_NO_ERR )
{
iprintf( "*** Error creating remote blink task\r\n" );
}
but I get the error 'array must be initialized with a brace-enclosed initializer'.
What is the right way to do this?
First, ParseBlinkOnCommand returns reference to local object and so return dangling reference.
Second C-array are not copyable, so int pattern2[3] = ParseBlinkOnCommand(rxbuffer); should be int (&pattern2)[3] = ParseBlinkOnCommand(rxbuffer);.
but why not using std::vector or std::array (or custom structure) ?
std::vector<int> ParseBlinkOnCommand(const char (&rxbuffer)[3])
{
// Code parses rxbuffer and creates the 3 ints needed
return {repeats, onTicks, offTicks};
}
And then
auto pattern2 = ParseBlinkOnCommand(rxbuffer);
if ( OSTaskCreate( BlinkLED,
pattern2.data(),
&BlinkTaskStack[USER_TASK_STK_SIZE],
BlinkTaskStack,
MAIN_PRIO - 1 ) != OS_NO_ERR )
{
iprintf( "*** Error creating remote blink task\r\n" );
}

How to know written var type with Clang using C API instead of actual?

I'm trying to use Clang via C API, indexing to be detailed. The problem is that some types are returned not as they are written, but as they are for compiler. For example "Stream &" becomes "int &" and "byte" becomes "int.
Some test lib:
// TODO make it a subclass of a generic Serial/Stream base class
class FirmataClass
{
public:
FirmataClass(Stream &s);
void setFirmwareNameAndVersion(const char *name, byte major, byte minor);
I'm using the code to get method information:
void showMethodInfo(const CXIdxDeclInfo *info) {
int numArgs = clang_Cursor_getNumArguments(info->cursor);
fprintf(stderr, " %i args:\n", numArgs);
for (int i=0; i<numArgs; i++) {
CXCursor argCursor = clang_Cursor_getArgument(info->cursor, i);
CXString name = clang_getCursorDisplayName(argCursor);
CXString spelling = clang_getCursorSpelling(argCursor);
CXType type = clang_getCursorType(argCursor);
CXString typeSpelling = clang_getTypeSpelling(type);
CXCursorKind kind = clang_getCursorKind(argCursor);
fprintf(stderr, " kind=[%s (%i)], type=[%s], spelling=[%s]\n",
cursor_kinds[kind], kind, clang_getCString(typeSpelling),
clang_getCString(spelling));
clang_disposeString(name);
clang_disposeString(spelling);
clang_disposeString(typeSpelling);
}
// return type
CXType returnType = clang_getCursorResultType(info->cursor);
CXString returnTypeSpelling = clang_getTypeSpelling(returnType);
fprintf(stderr, " returns %s\n", clang_getCString(returnTypeSpelling));
clang_disposeString(returnTypeSpelling);
}
Output:
[105:10 4689] access=[CX_CXXPublic]
kind=[CXIdxEntity_CXXInstanceMethod] (21)
name=[setFirmwareNameAndVersion] is_container=[0] 3 args:
kind=[CXCursor_ParmDecl (10)], type=[const char *], spelling=[name]
kind=[CXCursor_ParmDecl (10)], type=[int], spelling=[major]
kind=[CXCursor_ParmDecl (10)], type=[int], spelling=[minor]
returns void
So you can see that byte function arguments are described as int.
How can i get actual spelling?
Is byte declared via a typedef, or a #define?
When I declare these types:
typedef int MyType_t;
#define MyType2_t int
class Foo
{
public:
bool bar( MyType_t a, MyType2_t b );
};
And then print the type names I get from clang_GetTypeSpelling this is what I get:
bool Foo_bar( MyType_t a, int b )
Libclang presumably can't print the #defined name because the preprocessor has already replaced it with int by the time the parse tree is built.
I've solved this a few days ago.
"Stream &" becomes "int &" and "byte" becomes "int.
libclang doesn't know what Stream or byte are until you insert the standard headers manualy using the flag -isystem <pathToStdHeaderDirectory>
I wrote a C# function that retrieves all the visual studio VC headers include directory:
private static string[] GetStdIncludes()
{
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Wow6432Node\Microsoft\VisualStudio"))
{
if (key != null)
{
var lastVcVersions = key.GetSubKeyNames()
.Select(s =>
{
float result = 0;
if (float.TryParse(s, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out result))
return result;
else return 0F;
}).Where(w => w > 0F)
.OrderByDescending(or => or)
.Select(s => s.ToString("n1", System.Globalization.CultureInfo.InvariantCulture))
.ToArray();
foreach (var v in lastVcVersions)
{
using (var vk = key.OpenSubKey(v))
{
var val = (string)vk.GetValue("Source Directories");
if (!string.IsNullOrEmpty(val))
return val.Split(";");
}
}
}
}
throw new Exception("Couldn't find VC runtime include directories");
}
hope that helps
I was having the same issue with my own classes.
You need to pass on the same flags you would use for compiling with clang to either clang_parseTranslationUnit or clang_createTranslationUnit, in particular the -I flags which are used to look up the header files where your class or type definitions are.
it seems that if libclang can't find a type declaration, it just defaults to all of then to int.
calling clang_createIndex ( 1, 1 ) should provide you with hints on what you are missing via stderr.
Here is some sample code that works for me now:
int main ( int argc, char* argv[] )
{
char *clang_args[] =
{
"-I.",
"-I./include",
"-I../include",
"-x",
"c++",
"-Xclang",
"-ast-dump",
"-fsyntax-only",
"-std=c++1y"
};
CXIndex Idx = clang_createIndex ( 1, 1 );
CXTranslationUnit TU = clang_parseTranslationUnit ( Idx, argv[1], clang_args, 9, NULL, 0, CXTranslationUnit_Incomplete | CXTranslationUnit_SkipFunctionBodies );
clang_visitChildren ( clang_getTranslationUnitCursor ( TU ),
TranslationUnitVisitor, NULL );
clang_disposeTranslationUnit ( TU );
return 0;
}
I am trying to get the AST for a header file, hence the CXTranslationUnit_Incomplete | CXTranslationUnit_SkipFunctionBodies flags and -ast-dump -fsyntax-only command line options, you may want to omit them if you dont need them and of course add and change the -I parameters according to your needs.

seekg is not working

I am developing an MFC application using Visual C++ 2010
I am reading data for one file but It seems seekg is not working
Here is my code
//Transaction is a class i have defined before
void displayMessage(CString message)
{
MessageBox(NULL,message,L"error",MB_OK | MB_ICONERROR);
}
///////////////////////////////
ifstream input;
input.open("test.dat" , ios::binary );
if( input.fail() )
{
CString mess;
mess = strerror( errno );
mess.Insert(0,L"Error\n");
displayMessage(mess);
}
Transaction myTr(0,myDate,L"",0,0,L""); // creating an object of transaction
unsigned long position = 0;
while(input.read( (char *) &myTr , sizeof(Transaction)))
{
if(myTr.getType() == 400 )
position = (unsigned long)input.tellg() - sizeof(Transaction);
}
CString m;
m.Format(L"Pos : %d",position);
displayMessage(m);
input.clear();//I also tried removing this line
input.seekg(position,ios::beg );
m.Format(L"get pos: %d",input.tellg());
displayMessage(m);
input.close();
The first displayMessage shows This : Pos : 6716 But second one showes : get pos: 0
Why seekg is not working ?
Thanks
The problem is that CString.Format() is a varargs function and basic_istream::tellg() returns a pos_type which isn't a type that can be passed as a vararg agument so you get undefined behavior.
If you want to pass the position you get bace from tellg() to CString::Format() you'll need to cast it or put it in a temporary, intermediate variable:
unsigned long new_pos = input.tellg();
m.Format(L"get pos: %d", new_pos);