|
Hi all,
I'm working on a library of which I only want to distribute the .lib and a .h. The header defines the interface or api to the library, the idea being that the user does not bother much about the insides of it. However, I have a concept issue.
#include <map>
#include <string>
class MyApiClass{
public:
private:
std::map<std::string, Param> vars;
};
Obviously this throws an error saying Param is not defined when I compile another application that includes libApi.h and links the library. The thing is, the class Param is declared in Param.h and defined in Param.cpp, files that I don't want the user to play with.
What are my options??
Thanks in advance.
paul.
modified 9-Oct-14 10:12am.
|
|
|
|
|
What's wrong in including param.h in MyApiClass source file?
THESE PEOPLE REALLY BOTHER ME!! How can they know what you should do without knowing what you want done?!?!
-- C++ FQA Lite
|
|
|
|
|
well... the application in which I use the lib won't compile, will it?? Or am I missing something?
Including param.h in libApi.cpp , when compiling the application
#include "libApi.h"
void main (void)
{
}
I get an error saying "libApi.h: 'Param' undeclared identifier"
|
|
|
|
|
You can use the pimpl idiom:
class MyApiClass{
public:
private:
class MyApiClassImpl;
std::auto_ptr<MyApiClassImpl> impl;
};
and
#include <map>
#include <string>
#include "Param.h"
class MyApiClass::MyApiClassImpl
{
public:
private:
std::map<std::string, Param> vars;
};
MyApiClass::MyApiClass()
: impl(new MyApiClassImpl())
{}
int MyApiClass::SomeFunction()
{
return impl->SomeFunction();
}
MyApiClass::MyApiClassImpl::MyApiClassImpl()
{}
int MyApiClass::MyApiClassImpl::SomeFunction()
{
}
(Edited to fix code written too fast...)
modified 9-Oct-14 11:12am.
|
|
|
|
|
Your Approach only works as long as you are never required to pass a Param object as paramter or return one. Of course you could work with forward declaration (if you only pass references/pointers), but I would suggest another solution.
Create a libapi.hpp and include the headers in the correct order (i.e. map, string, Param.h, libApi.h). Consumers of your API inlclude the hpp. In the libApi.cpp you include the Param.h before the libApi.h. Then it should work.
The good thing about pessimism is, that you are always either right or pleasently surprised.
|
|
|
|
|
Ideally, you'd want minimal exposure, to ensure low coupling. The original post made a point of only showing Param in the private section, and said the user of the library should not be playing around with Param, so I assumed it was not a public type.
If the Param type was a public type used in the interface, the best solution would be to include Param.h in libApi.h instead of introducing a new file.
|
|
|
|
|
I am placing COM component (WMP) on dialog. When I place it and run the application, dialog does not appear but when I delete it and run, dialog appears.
Please suggest what can be issue?
I debug the code and saw DoModal function.
It is executing the portion of DoModal as m_hWnd is comiing NULL.
<pre lang="c++">
if (m_hWnd != NULL)
SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW|
SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
modified 9-Oct-14 7:54am.
|
|
|
|
|
Add the function AfxEnableControlContainer() in the InitInstance method of you app class.
«_Superman_»
I love work. It gives me something to do between weekends.
Microsoft MVP (Visual C++) (October 2009 - September 2013) Polymorphism in C
|
|
|
|
|
i have done my insertion code for the registration form but now i have to do password encryption after register which i totally have no idea on how to do it in C++ MFC dialog application. please help me if u have any source files. just encrypt the password part.
UpdateData();
MYSQL *ssock;
ssock = (MYSQL *)malloc(sizeof(MYSQL));
mysql_init(ssock);
conn = mysql_init(NULL);
if (conn == NULL) {
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
exit(1);
}
if (mysql_real_connect(conn, "127.0.0.1", "root", "Root", "inomatic", 0, NULL, 0) == NULL)
{
printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
exit(1);
}
int tmp = atoi((LPSTR)(LPCTSTR)m_Contact);
if(m_Password != m_CfmPassword)
{
MessageBox("Both Password do not match! Please enter again.");
m_EditPassword.SetFocus();
}
if(m_Username == "" || m_Password=="" || m_CfmPassword =="" || m_Email =="" || m_Contact =="" || m_Company == "")
{
MessageBox("Please fill in all the blanks.");
}
else if (m_Password == m_CfmPassword)
{
Insert(conn,(LPSTR)(LPCTSTR)m_Username,(LPSTR)(LPCTSTR)m_Password,(LPSTR)(LPCTSTR)m_Email,tmp,(LPSTR)(LPCTSTR)m_Company,"User");
MessageBox("Thank You! You have successfully registed into People Counter Application.");
}
UpdateData(FALSE);
mysql_close(conn);
m_EditUsername.SetSel(0,-1),m_EditPassword.SetSel(0,-1),m_EditCfmPassword.SetSel(0,-1),m_EditEmail.SetSel(0,-1),m_EditContact.SetSel(0,-1),m_EditCompany.SetSel(0,-1);
m_EditUsername.Clear();
m_EditPassword.Clear();
m_EditCfmPassword.Clear();
m_EditEmail.Clear();
m_EditContact.Clear();
m_EditCompany.Clear();
Winter
modified 8-Oct-14 9:09am.
|
|
|
|
|
As you were said in the previous post, this is the wrong forum for such questions.
Please search the right forum and post it there. Here is to post about the internal things of the site
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
Rating helpful answers is nice, but saying thanks can be even nicer.
|
|
|
|
|
Do not use encryption for passwords. You should add a salt value and use the two pieces of data to create a one-way hash which you store in your database. Remember, encrypted data can be decrypted, hashes cannot. There are many articles and samples explaining this in detail, including Secure Password Authentication Explained Simply[^].
|
|
|
|
|
A whipper-snapper (sort-of) on my team wrote this:
for (index = 0; index < num_systems && systems[index].type == SYSTEM_TYPE_XYZ && (systems[index].name, "XYZname"); ++index);
I don't care very much for excessive cleverness. I care for maintainability. And debug-ability. This does not meet that requirement for me.
Does anyone else feel this way? I am feeling old and curmudgeonly about this, however I want some honest opinions.
|
|
|
|
|
Here's my take on this.
If you need a minute to think about what a code statement does, then it has to go.
Get rid of it.
«_Superman_»
I love work. It gives me something to do between weekends.
Microsoft MVP (Visual C++) (October 2009 - September 2013) Polymorphism in C
|
|
|
|
|
Thank you. My confidence is bolstered.
|
|
|
|
|
No, and this is really not the place.
|
|
|
|
|
Sorry I bothered you. Please educate me: Where would you have posed the question?
|
|
|
|
|
The Lounge, or Weird & Wonderful. It's not a C/C++ question.
|
|
|
|
|
Quote: (systems[index].name, "XYZname") ?!?
THESE PEOPLE REALLY BOTHER ME!! How can they know what you should do without knowing what you want done?!?!
-- C++ FQA Lite
|
|
|
|
|
I know!
The line does not even do what the coder intends it to do. Too bad the compiler did not complain.
That alone is reason enough to 86 it, of course.
This program is rife with this kind of stuff. Some of it may even work, but as Superman says, I should not have to spend more than a moment understand it..
|
|
|
|
|
The result of that part of the condition would be the same as
static_cast<bool>(system[index].name)
The string literal will be evaluated but the result of the comma operator is always the leftmost argument. (You probably know that, but I thought I should offer an explanation for less experienced readers)
My guess is this was supposed to be a string comparison. Not that it makes the condition look any better...
Oh, and btw., I know that '??! ' is the trigraph for '| ', but I'm not familiar with '?!? '. Typo?
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
It's like a long paragraph with no commas or punctuation.
cheers
Chris Maunder
|
|
|
|
|
I have made a program with Outlookbar Class and a clistview class now, i'd like when i click in the Outlookbar automatically the view will take the focus. I have tried with SetFocus(). but nothing.
Can you indicate me the correct procedure?
i start with this line to geto pointer to the view
CView* pView = (CView*)GetActiveView();
It will not take you many time, so thanks in advance.
Giovanni
|
|
|
|
|
Hi everyone;
can someone help me with the program im doing..
1. i need to add and save student record without using database or text file.
2. view/search record.. that can be sort by category
3. edit record.
4. delete record
how am i suppose to do it???
hope someone could help..
|
|
|
|
|
Robin Percival Vibar wrote: how am i suppose to do it??? Yes, that's a good question: if you don't want to loose your changes every time your program exits then you have to use permanent storage, that is the hard disk (or another persistent medium like, for instance, flash memory of pen drives). Since you don't want to use a text file, I suppose a binary file is OK for you. You could design your own protocol or use object serialization. If you are using MFC , then you are lucky, since such framework provides good support to serialization, see "Serialization in MFC"[^].
THESE PEOPLE REALLY BOTHER ME!! How can they know what you should do without knowing what you want done?!?!
-- C++ FQA Lite
|
|
|
|
|
Hello Everybody,
I'm working on a simple C++ Project in VS 2013 Express. I'm trying to implement a TLS Callback function into a simple prog. What I want to do in future is to check for any present debuggers before the main (entrypoint) is called (...I know that most debuggers can handle TLS).
Here is my code so far and it works:
#include <windows.h>
#include <stdio.h>
using namespace std;
void WINAPI TLSCallback(PVOID DllHandle, DWORD dwReason, PVOID Reserved)
{
MessageBox(0, L"TLS Callback before main.", L"TLS CallBack", 0);
}
#ifdef _M_IX86
#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma comment (linker, "/INCLUDE:__xl_b")
#else
#pragma comment (linker, "/INCLUDE:_tls_used")
#pragma comment (linker, "/INCLUDE:_xl_b")
#endif
#ifdef _WIN64
#pragma const_seg (".CRT$XLB")
const
#else
#pragma data_seg (".CRT$XLB")
#endif
EXTERN_C
{
PIMAGE_TLS_CALLBACK _xl_b = TLSCallback;
#pragma data_seg ()
#pragma const_seg ()
}
int main(int argc, char* argv[])
{
printf("Hello World from main()!");
getchar();
return 0;
}
However, the really strange thing (at least to me) is, that if I switch in VS 2013 Express from Debug Configuration to Release Configuration and compile the project, AntiVir pops up with a message like "TR/Crypt.XPACK.Gen" found in compiled EXE. O.k. since TLS is also used by maleware I can basically understand that AntiVir doesn't like such things, but why does it not happen in Debug Configuration? Is there any way that it also would work in Release Configuration (Linker Options etc.?) ?
modified 4-Oct-14 5:22am.
|
|
|
|
|