|
you must say somewhere in you dll that glob_buf is defined (see extern keyword).
otherwise, why not making this :
char* StrTest() {
char* Buff = new char[14];
::strcpy(Buff, "Hell from DLL");
return Buff;
}
TOXCCT >>> GEII power [toxcct][VisualCalc]
|
|
|
|
|
Are you sure this will work ??
You try to write something at a NULL adress
Ok, but in fact the problem is not there. The problem is that VB and C++ don't use the same standard from strings. C++ uses zero-terminated strings and VB uses a kind of BSTR string (the length of the string is stored at the begning, each char takes 2 bytes and it is not zero-terminated).
You need to use a BSTR string inside your function and return it. I know this is a tricky problem and I spent a lot of time on this to find out a solution.
Sorry but I don't remeber exactly of the implementation details but take a look at BSTR strings (specifically this[^] article (and the functions at the end)
Hope this helps
|
|
|
|
|
This solution won't work neither
You will allocate memory in your dll and then return this string in the program. Two solutions: you don't delete the string -> this will result in a memory leak OR you delete the string and this will result in a runtime error because one basic rule is that the memory allocated by one process must be freed by the same process !! So here you allocate the string in the dll and free it in your program
|
|
|
|
|
If I understand your problem, you should allocate a string in the main process and pass his pointer to the dll function. In the dll function you can copy the string and then return to main process.
<br />
{<br />
char* str;<br />
str = new char[50];<br />
dll_func(str,50);<br />
<br />
<br />
}<br />
<br />
<br />
void dll_func(char* str, int max_size)<br />
{<br />
strcpy(str,"hallo world!");<br />
return;<br />
}<br />
|
|
|
|
|
Your idea was right as was your comment but your implementation does not use the max_size parameter. Shouldn't that be : strncpy( str, "hallo world", max_size ); ?
Just to be safe I would write the first part something like this :
<br />
<br />
const int strsize = 50;<br />
char* str;<br />
str = new char[strsize+1];<br />
dll_func(str,strsize);<br />
This way you will reserve a spot for a null character on the end.
|
|
|
|
|
Rick York wrote:
Your idea was right as was your comment but your implementation does not use the max_size parameter.
'couse I'm lazy! I thought that I solved that problem with my " //use max_size to prevent buffer overflow"
Rick York wrote:
Shouldn't that be : strncpy( str, "hallo world", max_size ); ?
yes.. this should a good implementation. Personally I usually use something like:
<br />
int dll_func(char* str,int max_size)<br />
{<br />
<br />
const char dll_str[] = "hallo world!";
<br />
strncpy(str,"hallo world!",max_size);<br />
return strlen(dll_str);<br />
}<br />
so in main process you can check (if (dll_func(str,strsize) > strsize) ) if you have truncated the string and the real/needed size.
Bye,
Francesco
|
|
|
|
|
Nothing of these will work in current context ! The problem is that the function is called from a VB program ! Thus, the first part will work (you can pass a string from VB in a C++ dll by specify it must be passed by val). But this will crash after when you try to read the string in VB. VB and C++ uses different string types...
|
|
|
|
|
cedric moonen wrote:
But this will crash after when you try to read the string in VB.
Oh.. I missed that!
Well.. I'm not using visual basic but I wrote some dll used by
Delphi programs. We solved the same iusse using simple types like
arrays of int/char instead of complex types like BSTR or pascal's string.
I suppose that you can pass to dll_func a Byte array and then convert it to a string.
Something like:
Dim ByteArrayString(50) As Byte
Here you can find something about bytearray to string conversion in Visual Basic.
Hope this help.
Bye,
Francesco
|
|
|
|
|
Hello All,
The following simple program that uses forward referencing does not
compile in my VC++ 6.0 compiler.
On the line where I define the member function
Pont2D::projectFrom(Point3D p3d) { ... }
the compiler complains that Point3D is undefined and refers to the
declaration at the beginning that tries to forward reference
the Point3D class. Here is the compiler output:
ForwardReference.cpp
ForwardReference.cpp(11) : error C2027: use of undefined type 'Point3D'
ForwardReference.cpp(4) : see declaration of 'Point3D'
ForwardReference.cpp(11) : error C2228: left of '.i' must have class/struct/union type
ForwardReference.cpp(11) : error C2027: use of undefined type 'Point3D'
ForwardReference.cpp(4) : see declaration of 'Point3D'
ForwardReference.cpp(11) : error C2228: left of '.j' must have class/struct/union type
Has any one encountered similar problem? Is there any command line option that would handle this issue?
Thanks.
Ganesh.
// ForwardReference.cpp: The First Line of the file
#include <iostream.h>
class Point3D; // Forward Declaration of class Point3D defined below.
class Point2D {
public:
int i, j;
Point2D() : i(0), j(0) {}
Point2D(int a, int b) : i(a), j(b) {}
void projectFrom(Point3D p3d) { i = p3d.i; j = p3d.j; } // compilation error
};
class Point3D { // being declared above, compiler ignores the defintion here.
public:
int i, j, k;
Point3D() : i(0), j(0) k(0) {}
Point3D(int ii, int jj, int kk) : i(ii), j(jj), k(kk) {}
Point3D& operator=(const Point2D& p2d) { i = p2d.i; j = p2d.j; k = 0;}
};
int main()
{
Point2D p2d(1,2);
Point3D p3d(2,3,4);
p2d.projectFrom(p3d);
cout << "p2d = (" << p2d.i << "' " << p2d.j << ").\n";
return 0;
}
// end ForwardReference.cpp
Ganesh
|
|
|
|
|
did you try to rebuild all your project ?
TOXCCT >>> GEII power [toxcct][VisualCalc]
|
|
|
|
|
I did try everything. I think this simple program does not any require such
building process anyway.
Ganesh
|
|
|
|
|
Ok, I see your problem.... To explain, the compiler finds the
void projectFrom(Point3D p3d) { i = p3d.i; j = p3d.j; } line difficult because the Point3D occupies a certain amount of memory (it doesn't yet know how many variable it has), and perhaps has a copy constructor (which the compiler might not yet know about). I'm not 100% sure here, but I think you have to change the Point3D p3d argument to Point3D &p3d - I think the compiler should cheer up then.
Joel Holdsworth
Wanna give me a job this summer?
Check out my online CV and project history[^]
|
|
|
|
|
Joel Holdsworth wrote:
I'm not 100% sure here, but I think you have to change the Point3D p3d argument to Point3D &p3d - I think the compiler should cheer up then.
Not really. He must not inline the function because he uses i = p3d there:
void projectFrom(Point3D p3d);
|
|
|
|
|
CP Visitor wrote:
Not really. He must not inline the function because he uses i = p3d there:
void projectFrom(Point3D p3d); // don't do this: { i = p3d.i; j = p3d.j; }
Purpose of inlining is optimization. Please see Bjarne Stroustrup
(C++ Prog. Lang., 3rd Ed, 1997, pages 675-676) on Ternary operation.
Ganesh
|
|
|
|
|
Ganesh_Srim wrote:
CP Visitor wrote:
Not really. He must not inline the function because he uses i = p3d there:
void projectFrom(Point3D p3d); // don't do this: { i = p3d.i; j = p3d.j; }
Purpose of inlining is optimization. Please see Bjarne Stroustrup
(C++ Prog. Lang., 3rd Ed, 1997, pages 675-676) on Ternary operation.
Forward declaration or oprimization. Chose one!
|
|
|
|
|
Bob Helter wrote:
Forward declaration or oprimization. Chose one!
CP Visitor is right.
Inlining can be done at the point of defining the function below the
definition of Point3D class. So nothing is lost.
Thanks
Ganesh
|
|
|
|
|
If you are not dead-set on using a pass-by-value or pass-by-reference then pass-by-pointer instead and your problem will be gone!
void projectFrom(Point3D p3d) { i = p3d.i; j = p3d.j; } // compilation error
void projectFrom(Point3D* p3d) { i = p3d->i; j = p3d->j; } // no compilation error
|
|
|
|
|
I tried everything honestly. Nothing works!
I hope its not a hardware instruction set problem!
Ganesh
|
|
|
|
|
I tried all your suggestions. But nothing worked.
The next thing I should suspect is some hardware instruction set bug!!
When I worked in Linux long time ago, I did not seem to encounter this problem!
Is there any way I can contact Micorsoft's personnel without having to purchase a subsciption.
I can't imagine programming without these constructs. But it is possible with virtual base classes containg the same data structure. Thus one ends up always using derived types when such a class is needed in a "cicular" way.
Ganesh
|
|
|
|
|
I made this little test program and it compiled and worked :
#include "stdafx.h"
class Point3D;
class Point2D
{
public:
int i, j;
Point2D() { Set( 0, 0 ); }
Point2D(int a, int b) { Set( a, b ); }
void Set( int a, int b ) { i = a; j = b; }
__inline void projectFrom(Point3D *p3d);
};
class Point3D
{
public:
int i, j, k;
Point3D() { Set( 0, 0, 0 ); }
Point3D(int a, int b, int c) { Set( a, b, c ); }
Point3D& operator=(const Point2D& p2d) { Set( p2d.i, p2d.j, 0 ); }
void Set(int a, int b, int c) { i = a; j = b; k = c; }
};
void Point2D::projectFrom(Point3D *p3d)
{
i = p3d->i;
j = p3d->j;
}
int main()
{
Point2D p2d(1,2);
Point3D p3d(2,3,4);
p2d.projectFrom( &p3d );
fprintf( stdout, "p2d = (%d, %d)\n", p2d.i, p2d.j );
return 0;
}
|
|
|
|
|
Rick York wrote:
void Point2D::projectFrom(Point3D *p3d)
... written below the class definition ;)
|
|
|
|
|
Hello CP Visitor.
You are right from the beginning. I misread the compiler remarks
as I put all function code in one line. Had I put those assigments on a
separate line, I would have at least undetstood that there is no
problem with forward referencing, but something else. I would have saved you all some time.
Thanks.
Ganesh
|
|
|
|
|
Hello 'Rick York'
Thanks for your time. Just before checking for messages,
I got it right finally. You are absolutely right. Since I put all
the code in one line, I could not decipher compiler message clearly.
Had I put the assignment code
<br />
{i = p3d.i; j = p3d.j; }
on a different line, I would have saved myself and all of you so much time.
My apologies.
Ganesh
Ganesh
|
|
|
|
|
Hello All,
I finally I uderstood the issue. Thanks everybody.
Ganesh
|
|
|
|
|
i used FindFirstChangeNotification()FindFirstChangeNotification()AND WaitForSingleObject() to notify any change in a mentioned directory.its working.But i want to mention the cause of notification (say its due to deletion of a file).i declared every filter condition in FindFirstChangeNotification()
|
|
|
|