|
This piece of code hasn't been sitting well with me since the beginning:
lenourien wrote:
LPSAFEARRAY pSA;
pSA= SafeArrayCreate(VT_BSTR,1,aDim);
if (pSA != NULL) {
BSTR element = SysAllocString((BSTR)words[low]);
unsigned int length = SysStringByteLen(element);
BSTR wcElement = NULL;
wcElement = SysAllocStringByteLen(NULL, length*2);
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,(LPCSTR)element
, -1, (LPWSTR)wcElement, length*2);
for(i = 0; i < wordcnt[low]; i++) {
if (hr= SafeArrayPutElement (pSA, &arrIndex, wcElement)){
SafeArrayDestroy(pSA);
}
SysFreeString (wcElement);
SysFreeString (element);
arrIndex++;
}
The problem here is that a BSTR is different from a C-string in that a BSTR knows its own length. In Visual Basic, a string can contain null (0) characters. In C, that signifies the end of a string, but in Visual Basic it can be part of the string.
MultiByteToWideChar is a function that takes and outputs normal C strings. The SysAllocString-functions take a C-string/length pair and output a BSTR. A BSTR is in fact a 2-byte unsigned integer representing the size of the string, followed by the actual unicode (16 byte) character array. The catch here is that the address the BSTR references (BSTR is a wchar_t*) is to the actual character array. If you take the pointer (a BSTR) and go back 2 bytes, you can read the size field. So, in the code above: *((unsigned short*)(wcElement - 1)) returns the size of wcElement (the actual size! Not the C-size counted to the 0-char, but the actual allocated size, which is VB wise 'the' size). SysAllocStringByteLen is a weird function, in that it puts an ANSI (1 byte) string flatly into a unicode (2 bytes) string without doing a widening conversion.
Furthermore, SysAllocString expects to be given a unicode string, and not a char*, as words is. So, your code now greatly risks reading outside the buffer. It doesn't because words at some point has two 0-chars after each other, which the Sys function recognises as a unicode 0-char and stops on time. But actually, it's reading through words way too far.
So, knowing this, you can for one conclude that the code is wrong in almost every way, but also actually that you can simplify your code a little and make it right.
What you do is you loop through each words list and use strlen to find the length of the words entry. Then you use MultiByteToWideChar to convert to unicode. Then you use SafeArrayPutElement to store the converted string. And this you repeat for every entry of words.
for (i = lowerBoundary; i <= upperBoundary; i++)
{
size_t len = strlen(words[i]); BSTR element = SysAllocStringLen(NULL, len); MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, words[i], len, (LPWSTR)element, len);
SafeArrayPutElement(pSA, &i, element);
SysFreeString(element);
}
I think this code should work correctly, but you should check this and see how it fits into the rest yourself.
Finally, in the first piece where you receive StringArray you are taking into account the lower and upper boundary of the array, but then in the rest of the code you assume lower boundary is 0. This is a bug you'll need to fix as well.
At any rate, I'm fairly sure this is where your current problem is stemming from: from SysAllocString copying too many bytes from words[low].
|
|
|
|
|
Where's the bowing down and low smiley here?????
Your code not only worked perfectly it also got rid of a nasty several seconds freeze on the vb side while the dll was freeing memory.
I don't know how to thank you (it's not like my coding skills are ever going to help you although if you're ever interested I'm much better with html & css )
For the lower and upper bound that I check at the beginning, I agree I should do something about that and it would probably be safer to do it but the truth is that the lower boundary here is always 0 as I just let the arrays do their work normally without ever specifying the lower boundary myself. But I want to learn so you're right I'll implement it.
So many thanks again
|
|
|
|
|
You're welcome
Good luck with the rest of your program. I'm guessing you learned quite a bit already from this, seeing as how you solved most of your problems with only a gentle nudge on our side. Keep learning and you'll be lecturing me soon 
|
|
|
|
|
fingers crossed 
|
|
|
|
|
My pc has Windows 7.
Iam creating connection to a terminal server, using WTSOpenServer() API.
And with the created handle, if i try to transmit message to any other machine other than mine using WTSSendMessage() API, iam getting the GetLastError() as "RPC server unavailable".
can anyone of you pls suggest what would be the solution for this.
Thanks,
Arun P.
|
|
|
|
|
Immediate suggestions that come to mind:
- Try disabling any and all firewalls on both PCs.
- Check the RPC services are all enabled and started and functioning properly (You'll have to look these up.)
- Try some of the Microsoft samples first and see if they run without problem.
|
|
|
|
|
Hi
i have a little knowledge about VC++.
My question is how i can convert a simple ado data type to c++ data type. for example if i want to know the number of rows in a sql table, i should run a sql command like "select count(*) from table tbl", but how i can store the answer of this query in a c++ integer data type?
thanks
|
|
|
|
|
Once you exectue the query, the count will be the data value in the first (only) row, first column of the resultant recordset. So, you will get the data value of the first field as a _variant_t.
Pseudocode:
// Assume you executed: select count(*) as mycount from table
pField = recordSet->Fields->GetItem(_variant_t("mycount"));
_varint_t val = pField->GetValue();
int count = val.iVal;
John
|
|
|
|
|
Hi ,
I have a template class like
template<typename t="">
public ref class MyBaseclass.
I need to inherit this class on another one like.
public ref class Derivedclass:MybaseClass<string>.
Could you please let me know whats the syntax for doing like this ?Sorry I am new to VC++.
|
|
|
|
|
template<typename T>
ref class Base
{
public:
Base(T value) : _value(value) {}
T get_value() { return _value; }
private:
T _value;
};
ref class Derived : Base<String^>
{
public:
Derived(String^ value) : Base(value) {}
};
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
#pragma once
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#pragma comment (lib, "Ws2_32.lib")
#include "stdafx.h"
#include <Winsock2.h>
#include <Ws2tcpip.h>
#include "vcclr.h"
#include<string>
#include<iostream>
#include <windows.h>
#include <process.h>
#include <stdio.h>
#include <sstream>
#include <stdlib.h>
namespace trial {
using namespace std;
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Threading;
using namespace System::Runtime::InteropServices;
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
}
public:
~Form1()
{
if (components)
{
delete components;
}
}
public: System::Windows::Forms::Button^ baslat_button;
public:
private:
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
void InitializeComponent(void)
{
}
#pragma endregion
public: void start1(void* pParams )
{
}
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
{
}
private: System::Void baslat_button_Click(System::Object^ sender, System::EventArgs^ e)
{
hEvent1 = CreateEvent( NULL, FALSE, TRUE, NULL );
hEvent2 = CreateEvent( NULL, FALSE, FALSE, NULL );
_beginthread(start1, 0, NULL );
}
};
}
im working on visual studio 2010 ultimate,
When i compile the code i have got an error "beginthread" line
Error 1 error C3867:
How can i fix this problem?
|
|
|
|
|
By following the advice in the error message, and use the address of start1 in your _beginthread() call thus:
_beginthread(&start1, 0, NULL );
|
|
|
|
|
Hi, dear all,
I have a C++ project created in VS2003, now I convert it to VS2008, after fix some compile errors and setting change, it compiles ok and can be started.
This project application is an EXE file, not DLL file.
When I create a dialog object and call dlg.doModal(), get afxwin1.inl ASSERT error in AfxGetResourceHandle().
But the project works fine in VS2003.
Can anybody tell me what causes this issue and how to fix it?
Thanks!
|
|
|
|
|
Without seeing the actual code and the specific details of the ASSERT it is not very likely that we can guess what is going wrong.
|
|
|
|
|
CEditDlg *m_editDlg = new CEditDlg(this,propComp,propComp->Getbitmap(), propComp->GetType(),pWnd);
m_editDlg->SetEditComp(propComp);
m_editDlg->DoModal();
Error happens when call DoModal(). I debug inside the codes and see the error occurs becuase afxCurrentResourceHandle is NULL.
_AFXWIN_INLINE HINSTANCE AFXAPI AfxGetResourceHandle()
{ ASSERT(afxCurrentResourceHandle != NULL);
return afxCurrentResourceHandle; }
It seems the resouce doesn't attache to the project, right, how can I solve it?
|
|
|
|
|
Since this is your own dialog you need to review the constructor to ensure you are correctly instantiating from a base CDialog() [^] class.
|
|
|
|
|
I told you everything works fine in VS2003. Also in VS2008 Release mode.
Yes,my dialog inherits from Dialog class, and in instructor, I do something like the following:
CEditDlg::CEditDlg( System::Object * mainApp, NCGenericCompont* pCompont, UINT menuSel, CString type,CWnd* pParent /*=NULL*/)
: CDialog(CEditDlg::IDD, pParent)
The codes should have no problem, the problem should be it cannot locates the resource file, there are a lots of people ask this questions about this in internet, but seems cannot find answer.
|
|
|
|
|
Well it's always possible this is a bug that should be reported to Microsoft.
|
|
|
|
|
Hi, Please check whether ur object is created properly before u call the domodal().
If it is fine, keep the break point in the dialog class's "oninitdialog" function and move forward step by step.
I guess the issue would be in any of the controls u have used.
Thanks,
Arun P.
|
|
|
|
|
Hi all, I am working on class to wrapp unmanaged pointer. I am just confused, whether pinning of value struct is needed in C++/CLI, i.e. whether if I will not do it, it can cause some problems.
In C#, I am not able to fix structs:
Point pntA = new Point(10, 25);
Point pntB = new Point();
unsafe
{
fixed (Point* ptrA = &pntA, ptrB = &pntB)
{
ptrB->X = ptrA->X;
ptrB->Y = ptrA->Y;
}
}
but, I can simply use address-of operator:
Point pntA = new Point(10, 25);
Point pntB = new Point();
unsafe
{
Point* ptrA = &pntA, ptrB = &pntB;
ptrB->X = ptrA->X;
ptrB->Y = ptrA->Y;
}
What is confusing me is that pin_ptr lets me pin structures as well as use address-of operator:
generic <typename T> where T : value struct
T GetValueA(void* ptr)
{
T val = Activator::CreateInstance<T>();
pin_ptr<T> valPtr = &val;
memcpy(valPtr, ptr, sizeof(T));
return val;
}
generic <typename T> where T : value struct
T GetValueB(void* ptr)
{
T val = Activator::CreateInstance<T>();
memcpy(&val, ptr, sizeof(T));
return val;
}
My questions are:
Is pinning needed in C++/CLI functions to fix value struct
before using its pointer in unmanaged function?
Are value structs allocated in the unmanaged heap?
Thanks all,
Dusan
|
|
|
|
|
Hi,
I have created a checkbox using MFCRibbonCheckBox. Depending on certain conditions i want to disbale it.
But it does not have any property for disabling. Can anybody help me out?
thanx in advance
|
|
|
|
|
Hello everybody.
I'm doing a little project for my B.Sc degree, in which i need to retreive tcp parameters and proceess them.
I'm kinda new to all this socket proggraming and network progamming, can you help me with writing a proggram that gets the TCP parameters in c++?
thanks
|
|
|
|
|
Assuming you are doing this in Windows then you can start here[^].
The best things in life are not things.
|
|
|
|
|
Richard's suggestion is accurate, but if you'd like to see what your target program should look like, see Wireshark[^]. If you're allowed to use libraries for your programs, Wireshark is based on a library called WinPCap[^] (which you can pull into your code and query to capture different types of traffic).
|
|
|
|
|
He's doing a BSc and cannot even start to research his chosen subject!
The best things in life are not things.
|
|
|
|
|