|
Hello
Below is my code about List Iterator. It is ok when
i compile it. But when i try to build it. the following
errors come up.
"DoubleOrderedLinkedList.obj : error LNK2019: unresolved external symbol "public: int __thiscall ListIterator::getNext(void)" (?getNext@?$ListIterator@H@@QAEHXZ) referenced in function _main"
Could any body here help me solve this problem?
Thanks,
Andre
------------------------------------------------
template
class DoubleOrderedLinkedList;
template
class ListIterator;
template
class Node
{
Object data;
Node * next;
Node * prev;
Node(const Object& newItem) :
data (newItem),
next (0),
prev (0)
{}
friend DoubleOrderedLinkedList<object>;
friend ListIterator<object>;
};
template
class DoubleOrderedLinkedList
{
Node<object>* head;
int numItems;
public:
DoubleOrderedLinkedList();
~DoubleOrderedLinkedList();
int size() const;
void Insert(const Object&);
void Remove(const Object&);
void Purge();
void displayList() const;
ListIterator<object> Iterator() const;
friend ListIterator<object>;
};
template
class ListIterator
{
int pos;
Node<object>* curr;
public:
ListIterator(Node<object>* const);
bool hasNext() const;
Object getNext();
bool hasPrevious() const;
Object getPrevious();
};
#include
#include "DoubleOrderedLinkedList.h"
#include "ListIterator.h"
using namespace std;
template
DoubleOrderedLinkedList<object>::DoubleOrderedLinkedList() :
head (0),
numItems (0)
{}
template
DoubleOrderedLinkedList<object>::~DoubleOrderedLinkedList()
{}
template
DoubleOrderedLinkedList<object>::size() const
{
return numItems;
}
template
ListIterator<object> DoubleOrderedLinkedList<object>::Iterator() const
{
ListIterator<object> it (head);
return it;
}
template
void DoubleOrderedLinkedList<object>::Insert(const Object& x)
{
Node<object>* previous = 0;
Node<object>* curr = head;
while ((curr != 0) && (curr->data < x))
{
previous = curr;
curr = curr->next;
}
Node<object> * const newNode = new Node<object> (x);
if (head == 0)
{
head = newNode;
}
else
{
if (curr == head)
{
newNode->next = curr;
curr->prev = newNode;
head = newNode;
}
else
{
if (curr != 0)
{
newNode->next = curr;
newNode->prev = curr->prev;
curr->prev->next = newNode;
curr->prev = newNode;
}
else
{
newNode->prev = previous;
previous->next = newNode;
}
}
}
numItems++;
}
template
void DoubleOrderedLinkedList<object>::displayList() const
{
Node<object>* ptr = head;
cout << "[ ";
while (ptr != 0)
{
cout << ptr->data << " ";
ptr = ptr->next;
}
cout << " ]" << endl;
}
int main()
{
DoubleOrderedLinkedList l;
l.Insert(10);
l.Insert(5);
l.Insert(15);
l.displayList();
ListIterator it = l.Iterator();
cout << "Testing Iterator" << endl;
while (it.hasNext())
{
cout << it.getNext() << endl;
}
}
#include "DoubleOrderedLinkedList.h"
#include "ListIterator.h"
template
ListIterator<object>::ListIterator(Node<object>* const p) :
pos (0),
curr (p)
{}
template
bool ListIterator<object>::hasNext() const
{
return (pos < numItems);
}
template
Object ListIterator<object>::getNext()
{
if (hasNext())
{
Object item = curr->data;
if (curr->next != 0) {
curr = curr->next;
}
pos++;
return item;
}
else
{
//throw(Exception("No Such Element");
}
}
template
bool ListIterator<object>::hasPrevious() const
{
return (pos > 0);
}
template
Object ListIterator<object>::getPrevious()
{
if (hasPrevious())
{
if ((curr.prev != 0) && (pos < numItems))
{
curr = curr->prev;
}
Object item = curr->data;
pos--;
return item;
}
else
{
//throw(Exception("No Such Element");
}
}
|
|
|
|
|
that message is given when in the header file you wrote a function that in the cpp file is not used
Written by: Rafael Fernández López.
void life ( bool me, bool her )
{
if ( her )
{
me = true ;
}
else
{
me = false ;
} }
|
|
|
|
|
You must have the implementation of your template class in the header file. Just copy all the functions from the .cpp file into the header file and it'll work.
And while you are at it, pick up a book on C++ and read very carefully in the chapter which handles templates.
--
Watcha' gonna do, when Hulkamania runs wild on you!?
|
|
|
|
|
Is anyone aware if it is possible to pass a db handle between two seperate applications? And if so how is this accomplished... do you utilize the command line of the CreateProcess command. And if so, how would you pass it (not sure how you would convert it to a string etc). What i am trying to accomplish is not to have to open the same DB on new instances of programs designed to perform certain task. This is an ODBC connection as well. Any insight is appreciated
|
|
|
|
|
Johnny Quintanilla wrote:
...is possible to pass a db handle between two seperate applications?
By applications (and the mention of CreateProcess() ), do you mean EXEs? If so, information sent to the spawned application is on the command-line. I'm not sure a handle would be valid across a process boundary.
A rich person is not the one who has the most, but the one that needs the least.
|
|
|
|
|
>Is anyone aware if it is possible to pass a db handle between two seperate applications?
Behavior varies from one database to another, from driver, etc etc etc.
With Oracle sqlnet api handle may be can passed btw processes, also not supported.
SqlLib handle, sqllib api can be passed safely cross boundary and I think is supported.
ODBC drivers do NOT support such behavior, it may or may not work with next update of oracle or vendor driver.
Proper solution would be to build out of process STA com object, that performs access to database.
|
|
|
|
|
Handles are most often bound to the process in which it was acquired. ODBC handles fall into that category!
The post above this one mentions building an out-proc COM server for doing the actual database acces. This may or may not suit your needs. Is it necessary to share the actual connection between the processes? If not, then you can just pass the source DSN to the other processes. Otherwise, the COM server is your best shot.
--
Watcha' gonna do, when Hulkamania runs wild on you!?
|
|
|
|
|
Dear friend,
I met a database assert error when I execute my program. My coding is
//======================= main.cpp=============================
//-------------------------------------------------------------
// optional information, such as a user ID and password.
// For example, "DSN=SQLServer_Source;UID=SA;PWD=abc123"
//
BOOL OpenDataBase(CDatabase *db)
{
CString connect;
BOOL openOK;
openOK = TRUE;
connect += "UID=Admin;";
connect += "PWD=anson;"; // Password of file is anson
connect += "DRIVER={Microsoft Access Driver (*.mdb)};";
connect += "DBQ=";
connect += "./database/pmsdb.mdb";
char teststr[255];
try
{ db->OpenEx(connect, CDatabase::noOdbcDialog);
}
catch ( CDBException* e)
{
MessageBox(NULL, "DataBase file error.", "PMS Error
Message", MB_OK);
e->GetErrorMessage(teststr, 255);
MessageBox(NULL, teststr, "PMS Error Message", MB_OK);
e->Delete();
openOK = FALSE;
//throw; // this statement will terminate program at once.
}
//MessageBox(NULL, "Leaving", "Test", MB_OK);
return openOK;
}
//-----------------------------------------------------------------------------
// Name: SearchRecord()
// Desc: Look for required record
//-----------------------------------------------------------------------------
static bool SearchRecord(HWND hWnd, CDatabase *db)
{
COperationRecordset rst(db);
BOOL found;
found = FALSE;
rst.Open(CRecordset::dynaset);
while (!rst.IsEOF())
{
if (rst.v_Login_User == g_strlogin)
if (rst.v_Login_Password == g_strpassword)
// Successful Login set a ture value
found = TRUE;
rst.MoveNext();
}
return found;
}
///////////////////////////////////
// This event has been defined when a Space key is push
// Then, this dialog is use for login process
// Mesage handler for DIALOG box.
///////////////////////////////////
LRESULT CALLBACK DIALOGA(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
CDatabase db;
BOOL done= FALSE;
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if(LOWORD(wParam) == IDOK)
{
// UNIT GetDlgItemText(HWMD hDlg,int nID,LPSTR lpstr,int nMax);
GetDlgItemText(hDlg,IDLOGIN,g_strlogin,80); // get login bar text
GetDlgItemText(hDlg,IDPASSWORD,g_strpassword,80); // get password bar text
MessageBox(hDlg,TEXT("Testing Login proccess "),
TEXT("PMS Exit") , MB_YESNO);
// Open database
OpenDataBase(&db);
done = SearchRecord(hDlg, &db);
db.Close();
if (done=TRUE)
{g_FrameDisplay=1;}// Change the frame
else if (done=FALSE)
{
MessageBox(hDlg, "Sorry, Your input value did not find.Please try again !",
TEXT("PMS Login Error") , MB_ICONERROR|MB_OK);
}
//End Dialog
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
if ( LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
// =============COperationRecordset.cpp : implementation file============
//
//#include "stdafx.h"
#include "COperationRecordset.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// COperationRecordset
IMPLEMENT_DYNAMIC(COperationRecordset, CRecordset)
COperationRecordset::COperationRecordset(CDatabase* pdb)
: CRecordset(pdb)
{
//{{AFX_FIELD_INIT(COperationRecordset)
v_Login_User= _T("");
v_Login_Password= _T("");
//}}AFX_FIELD_INIT
m_nDefaultType = snapshot;
}
CString COperationRecordset::GetDefaultConnect()
{
return _T("ODBC;DSN=MS Access 97 Database");
}
// Table Name
CString COperationRecordset::GetDefaultSQL()
{
return _T("[Login]");
}
void COperationRecordset::DoFieldExchange(CFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(COperationRecordset)
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX, _T("[User]"), v_Login_User);
RFX_Text(pFX, _T("[Password]"), v_Login_Password);
//}}AFX_FIELD_MAP
}
/////////////////////////////////////////////////////////////////////////////
// COperationRecordset diagnostics
#ifdef _DEBUG
void COperationRecordset::AssertValid() const
{
CRecordset::AssertValid();
}
void COperationRecordset::Dump(CDumpContext& dc) const
{
CRecordset::Dump(dc);
}
#endif //_DEBUG
// ================COperationRecordset.h : header file===================
//
#include <afxdb.h>
#include <afx.h>
/////////////////////////////////////////////////////////////////////////////
// COperationRecordset recordset
class COperationRecordset : public CRecordset
{
public:
COperationRecordset(CDatabase* pDatabase = NULL);
DECLARE_DYNAMIC(COperationRecordset)
// Field/Param Data
//{{AFX_FIELD(COperationRecordset, CRecordset)
CString v_Login_User;
CString v_Login_Password;
//}}AFX_FIELD
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COperationRecordset)
public:
virtual CString GetDefaultConnect(); // Default connection string
virtual CString GetDefaultSQL(); // Default SQL for Recordset
virtual void DoFieldExchange(CFieldExchange* pFX); // RFX support
//}}AFX_VIRTUAL
// Implementation
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
};
Regards,
Anson Tong
|
|
|
|
|
How about trimming the code snippet down to just the relevant pieces? What line of what file is firing the assertion?
One thing that looks suspicious is that COperationRecordset 's constructor needs to assign the value 2 to m_nFields .
A rich person is not the one who has the most, but the one that needs the least.
|
|
|
|
|
The error message is
Debug assertion failed !
Progam : c:\FinalYearProject\work\debug\main.exe
File : dbcore.cpp
Line : 3282
For information on how your program cause an assertion failure, see the VC++ document on asserts.
Regards,
Anson Tong
|
|
|
|
|
The statement at line 3282 is:
ASSERT(m_nFields != 0);
My suspicion was right!
A rich person is not the one who has the most, but the one that needs the least.
|
|
|
|
|
I'm writing a dll and I want a .lib file to be produced. Problem is the file isn't being created. I have unchecked the "Doesn't produce .LIB" option under the Link tab in the project settings like I'm supposed to, but for some reason it still isn't producing the .lib and I don't remember how to fix this.
So what do I need to do? I'm using VC++ 6.0
Thanks!
|
|
|
|
|
That checkbox never worked for me....
I would modify .dsp to:
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
TargetPath=.\Release\My.lib
from
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 /nologo /subsystem:windows /dll /machine:I386
|
|
|
|
|
When I use the MAPISendMail command with the MAPI_DIALOG flag it brings up the dialog in Outlook (loading mapi32.dll library) and Outlook Express (loading msoe.dll library). If the mail client is closed, the message will send in Outlook Express, but will sit in the outbox of Outlook until the program is opened and the send/receive button is pressed.
How can I change this behavior?
I can't create a new process of outlook.exe because I do not know if the mail has been sent before killing the process...
Help please, last time I submitted this question I only got one response (which unfortunately did not work out). Thank you in advance...
~LizardWiz()
|
|
|
|
|
Can you provide a code snippet of how you are using the mail API?
A rich person is not the one who has the most, but the one that needs the least.
|
|
|
|
|
This is sort of it, except that I am also attaching a file with a MapiFileDesc structure...
LPMAPILOGON lpfnMAPILogon;
LPMAPISENDMAIL lpfnMAPISendMail;
LPMAPILOGOFF lpfnMAPILogoff;
LHANDLE lhSession;
HMODULE hMAPILib;
MapiRecipDesc sender =
{
0,
MAPI_ORIG,
"anyone",
"anyone@anywhere.com",
0,
NULL
};
MapiRecipDesc recipient =
{
0,
MAPI_TO,
"someone@anywhere.com",
NULL,
0,
NULL
};
MapiMessage message =
{
0,
"Some subject",
"Some message text",
NULL,
NULL,
NULL,
0,
NULL,
1,
&recipient,
0,
NULL
};
hMAPILib = LoadLibrary("either MAPI32.DLL or MSOE.DLL depending on MSO or MSOE");
lpfnMAPILogon = (LPMAPILOGON)GetProcAddress(hMAPILib, "MAPILogon");
lpfnMAPISendMail = (LPMAPISENDMAIL)GetProcAddress(hMAPILib, "MAPISendMail");
lpfnMAPILogoff = (LPMAPILOGOFF)GetProcAddress(hMAPILib, "MAPILogoff");
(*lpfnMAPILogon)(0, NULL, NULL, 0, 0, &lhSession);
(*lpfnMAPISendMail)(lhSession, 0, &message, MAPI_DIALOG, 0);
(*lpfnMAPILogoff)(lhSession, 0, 0, 0);
FreeLibrary(hMAPILib);
~LizardWiz()
|
|
|
|
|
Essentially, later versions of Outlook are configured to do this, so as to slow the spread of email worms. See:
http://support.microsoft.com/?kbid=290499[^]
for information on how to alter this (and other security-related) behavior.
Note: as far as i'm aware, this does not apply to Extended MAPI, so you may wish to give that a look. Or just tell your users it's for their own good.
Zno one puts flowers on a flower's grave
|
|
|
|
|
Hi you out there,
I'm a C++ beginner trying to pass one (two) array(s) to a function but
the problem now is that I got different versions of passing such an array
to a function...
Please consider the following example:
I've got a two pre-defined array of let's say six elements:
int MyArray[6];<br />
int MySecondArray[6];
Now I wrote a functions - it even works - that uses the first array to change the second.
It is declared as follows:
void ChangeSecondArray(const int pFirst[], int pSecond[])
{<br />
if(pFirst[0] == 7)<br />
pSecond[2] = 5;<br />
}
The only thing I want to know is: Does this code only work because I use VC++ 6.0 or is it actually correct the way I've coded it? If not, would one of you please be so kind and tell me how to do it correctly (please remember: I know the size of the array prior to using it within the function, it never changes).
Thanks in advance,
pf7
|
|
|
|
|
You have coded it correctly. Were you to change the statement to if (pFirst[0] = 7) instead, you would receive the expected error message.
A rich person is not the one who has the most, but the one that needs the least.
|
|
|
|
|
Sorry, I haven't been at home for a while, so I wasn't able to reply to your answer
Thank you for the quick 'n easy answer
pf7
|
|
|
|
|
pf7 wrote:
I'm a C++ beginner trying to pass one (two) array(s) to a function
If you're coding in full C++ without support for legacy C code, I would suggest that you pass vectors[^] instead of arrays. It may seem intimidating at first, but I feel it would be worth learning.
~Nitron.
ññòòïðïðB A start
|
|
|
|
|
Hello,
I'm using Visual C++ 6, and I'm trying to duplicate my work from the Borland complier. I want to hook interrupt functions via the 'interrupt' keyword but it seems the Visual complier does not support this keyword. Also I've tried using _dos_getvect() and _dos_setvect() but again the complier won't have it.
Is it possible to do what I'm trying to do under Visual C++ 6?
The project I built is Win32 console application.
Many thanks for any help.
|
|
|
|
|
Joe_G wrote:
Also I've tried using _dos_getvect() and _dos_setvect() but again the complier won't have it.
That's because those are old 16-bit conventions. You can do inline assembler using the _asm keyword.
A rich person is not the one who has the most, but the one that needs the least.
|
|
|
|
|
I hope you know that interrupt handling and hardware access are very different in the Win32 environment than your experience under MS-DOS (which I'm guessing from the _dos_getvect() and _dos_setvect() references in your message).
Your problems with the compiler are deliberate choices on Microsoft's part. VC6 is designed to produce only executables that run in a Windows environment, so they saw no need to provide hardware access. You won't find library support for interrupts or port I/O. You can achieve these things using _asm blocks, of course, but that leads us to the next problem.
As a rule, the Win32 environment disallows hardware access by applications. Period. The purpose of this is to protect system integrity from ill-behaved applications. Now, there are differences depending upon which version of Windows you are developing for.
I've not programmed for it in a long while, but there may be enough of the DOS subsystem present to let you play with the interrupts under Windows 9x/ME. There are constraints, but I don't know if they completely prevent you from accessing the interrupt structure.
Under Windows NT/2000/XP, you are completely out of luck. NT and its successors reserve interrupt access to device drivers only. The best thing that will happen to your application if it tries to replace/intercept an interrupt is that it will terminate with an exception.
If you absolutely have to deal with hardware directly, you're going to have to learn about device drivers in the Win32 environment, which is distinctly non-trivial.
Software Zen: delete this;
|
|
|
|
|
I have a string specifying the user name in the format: "domain\username". My question is: How can I get the group to witch the user belongs to?
I searched API's but couldn't find anything all I could find was "LookupAccountName" but it is not what I'm looking for. Please help if you know something. Thank's
|
|
|
|
|