473,698 Members | 1,996 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Why won't this cast?

class SORef {...};
class SelectedFORef : public SORef {...};
SOFORef SOCastToSOF(SOR ef sor) {
SelectedFORef sof=nil;
sof=dynamic_cas t<SelectedFORef >(sor);
return sof;
};

I am getting a problem where sor is not being cast to sof (becomes nil)
even though sor IS a SelectedFORef underneath. (I have a debug method
with details contents and type).

I am not a C++ expert.
What am I doing wrong?

Mark
May 25 '07
18 3113
mark wrote:
In article <GY************ **@newsfe6-win.ntli.net>,
John Harrison <jo************ *@hotmail.comwr ote:
>mark wrote:
>>In article <5b************ **@mid.individu al.net>,
Ian Collins <ia******@hotma il.comwrote:

mark wrote:
In article <5b************ *@mid.individua l.net>,
Ian Collins <ia******@hotma il.comwrote:
>
>mark wrote:
>>In article <5b************ *@mid.individua l.net>,
>> Ian Collins <ia******@hotma il.comwrote:
>>>
>>>mark wrote:
>>>>class SORef {...};
>>>>class SelectedFORef : public SORef {...};
>>>>>
>>>>>
>>>>SOFOR ef SOCastToSOF(SOR ef sor) {
>>>> SelectedFORef sof=nil;
>>>What's nil?
>>nil == NULL.
>>Pascal version of NULL.
>Then why hide it? You can't assign NULL to a class object, only a
>pointer.
>>
>You can't apply a dynamic_cast to a class object, only a reference of a
>pointer to one.
I am idiot.
Sorry.
Should be:
>
class SOObject {...};
typdef class SOObject * SORef;
>
class SelectedFileObj ect : public SOObject {...};
typedef class SelectedFileObj ect * SelectedFORef;
>
It's seldom, if ever, a good idea to hide pointer types behind typedefs.
Have to. The class pointer is available to plugins. And C++ doesn't like
plugins. So I typedef as a struct * for plugins and use accessor
routines.
That's not a reason that makes any sense to me, (not saying it is wrong
though).
>>>>SOFORef SOCastToSOF(SOR ef sor) {
This is an accessor routine for plugins.
The debugger shows it to still be a SelectedFORef class instance.

SelectedFORef sof=nil;
sof=dynamic_cas t<SelectedFORef >(sor);
return sof;
};
Why not

SelectedFORef sof = dynamic_cast<Se lectedFORef>(so r);
Did try that. Makes no difference.
Would the typedef actually screw things up?
No.

Does class SOObject have at least one virtual function? You need at
least one virtual function for dynamic_cast to work.

When you say the cast is not working, what *exactly* do you mean? How
can you tell the cast is not working?
Mac OS X gdb debugger.
Inspecting sor with XCode/gdb shows it to be a SelectedFileObj ect
underneath. It's type is listed as such and not the base class SORef.
So the dynamic_cast should work (according to the C++ book I have,
Right, so before you do the cast you definitely have a
SelectedFileObj ect, but if was after that I was wondering about. Does
NULL get assigned to sof, or something else? I'm asking how you know it
failed, not why you expect it to work. Just trying to eliminate all the
possibilities.

john
May 25 '07 #11
In article <j3************ ***@newsfe4-win.ntli.net>,
John Harrison <jo************ *@hotmail.comwr ote:
mark wrote:
In article <GY************ **@newsfe6-win.ntli.net>,
John Harrison <jo************ *@hotmail.comwr ote:
mark wrote:
In article <5b************ **@mid.individu al.net>,
Ian Collins <ia******@hotma il.comwrote:

mark wrote:
In article <5b************ *@mid.individua l.net>,
Ian Collins <ia******@hotma il.comwrote:

mark wrote:
>In article <5b************ *@mid.individua l.net>,
> Ian Collins <ia******@hotma il.comwrote:
>>
>>mark wrote:
>>>class SORef {...};
>>>class SelectedFORef : public SORef {...};
>>>>
>>>>
>>>SOFORe f SOCastToSOF(SOR ef sor) {
>>> SelectedFORef sof=nil;
>>What's nil?
>nil == NULL.
>Pascal version of NULL.
Then why hide it? You can't assign NULL to a class object, only a
pointer.
>
You can't apply a dynamic_cast to a class object, only a reference of a
pointer to one.
I am idiot.
Sorry.
Should be:

class SOObject {...};
typdef class SOObject * SORef;

class SelectedFileObj ect : public SOObject {...};
typedef class SelectedFileObj ect * SelectedFORef;

It's seldom, if ever, a good idea to hide pointer types behind typedefs.
Have to. The class pointer is available to plugins. And C++ doesn't like
plugins. So I typedef as a struct * for plugins and use accessor
routines.
That's not a reason that makes any sense to me, (not saying it is wrong
though).

SOFORef SOCastToSOF(SOR ef sor) {
This is an accessor routine for plugins.
The debugger shows it to still be a SelectedFORef class instance.

SelectedFORef sof=nil;
sof=dynamic_cas t<SelectedFORef >(sor);
return sof;
};
Why not

SelectedFORef sof = dynamic_cast<Se lectedFORef>(so r);
Did try that. Makes no difference.
Would the typedef actually screw things up?
No.

Does class SOObject have at least one virtual function? You need at
least one virtual function for dynamic_cast to work.

When you say the cast is not working, what *exactly* do you mean? How
can you tell the cast is not working?
Mac OS X gdb debugger.
Inspecting sor with XCode/gdb shows it to be a SelectedFileObj ect
underneath. It's type is listed as such and not the base class SORef.
So the dynamic_cast should work (according to the C++ book I have,

Right, so before you do the cast you definitely have a
SelectedFileObj ect, but if was after that I was wondering about. Does
NULL get assigned to sof, or something else? I'm asking how you know it
failed, not why you expect it to work. Just trying to eliminate all the
possibilities.

john
SelectedFORef sof=nil; <-- habit of setting vars to defaults.

sof=dynamic_cas t<SelectedFORef >(sor); <-- sof is set to nil/NULL by
dynamic_cast

This routine is invoked by a plugin. sor is passed from APP -PLUGIN
-APP (above routine). The plugin just has a pointer to work with.
May 25 '07 #12
In article <w8************ ****@newsfe4-win.ntli.net>,
John Harrison <jo************ *@hotmail.comwr ote:
>>>I am idiot.
Sorry.
Should be:

class SOObject {...};
typdef class SOObject * SORef;

class SelectedFileObj ect : public SOObject {...};
typedef class SelectedFileObj ect * SelectedFORef;

[snip]

Here's the full class definitions.

class SelectedObject {
UInt16 refCt;

[snip]

//-----------------------------------------------------------------------
--------------

class SelectedFileObj ect:public SelectedObject {
OSType sfoReady;
protected:

[snip]

typedef class SelectedFileObj ect* SelectedFORef;
typedef SelectedFORef SOFORef;

There's some confusion here

In your original code, the base class is called SOObject, in the class
definitions posted more recently, it's SelectedObject.

Could this be the problem, are you getting mixed up with your names?

john
No.
The original posts were off the top of my head. Couldn't remember the
spellings.
I am not having a very intelligent day today.
The actual routine is this:

SOFORef SOCastToSOF(SOR ef sor) {
SelectedFORef sof=nil;
sof=dynamic_cas t<SelectedFORef >(sor);
return sof;
};

Classes as given in previous post.

I changed the above to this:

OFORef SOCastToSOF(SOR ef sor) {
if (sor==nil) {return nil;}
SelectedFORef sof=nil;
printf("%s\n", typeid(*sor).na me());
printf("%s\n", typeid(Selected FileObject).nam e());
if (typeid(*sor)== typeid(Selected FileObject)) {
sof=(SOFORef)so r;
}
else {sof=nil;}
// sof=dynamic_cas t<SelectedFORef >(sor);
return sof;
};

The typeid.name() for '*sor' & 'SelectedFileOb ject' returned
'18SelectedFile Object'.
But the typeid(*sor)==t ypeid(SelectedF ileObject) evaluates to false.
May 25 '07 #13
mark wrote:
>
SelectedFORef sof=nil; <-- habit of setting vars to defaults.
Pointless when it gets assigned on the next line...
sof=dynamic_cas t<SelectedFORef >(sor); <-- sof is set to nil/NULL by
dynamic_cast

This routine is invoked by a plugin. sor is passed from APP -PLUGIN
-APP (above routine). The plugin just has a pointer to work with.
What is a plugin? The objects aren't being mangled by another language
by any chance?

--
Ian Collins.
May 25 '07 #14
In article <5b************ **@mid.individu al.net>,
Ian Collins <ia******@hotma il.comwrote:
mark wrote:

SelectedFORef sof=nil; <-- habit of setting vars to defaults.
Pointless when it gets assigned on the next line...
sof=dynamic_cas t<SelectedFORef >(sor); <-- sof is set to nil/NULL by
dynamic_cast

This routine is invoked by a plugin. sor is passed from APP -PLUGIN
-APP (above routine). The plugin just has a pointer to work with.

What is a plugin? The objects aren't being mangled by another language
by any chance?

They shouldn't as the plugin (loadable bundle/library) only recieves a
pointer.

The plugin uses this definition:
// parent class
typedef void* SelectedObjectR ef;
typedef SelectedObjectR ef SORef; // shorter name

// selected file objects
typedef void* SelectedFileObj ectRef; // subclass of SORef
typedef SelectedFileObj ectRef SOFORef;

The plugins are not necessarily written in C++.
The test plugin is written in C.

Also, some testing shows that if the object passes through the plugin,
the casting fails. Otherwise if the casting routine is called directly
by the owning app, it succeeds. This means there is some mangling going
on somewhere.
May 25 '07 #15
On May 25, 9:58 am, mark <trid...@ihug.c o.nzwrote:

[...]
The typeid.name() for '*sor' & 'SelectedFileOb ject' returned
'18SelectedFile Object'.
But the typeid(*sor)==t ypeid(SelectedF ileObject) evaluates to false.
I'm just guessing, since I don't know the environment in which
you are working. But you did mention something about the actual
objects being in a plugin. So this really have nothing to do
with C++ (which doesn't support plugins, yet), but are you
loading (under Unix) or building (under Windows) the plugin
correctly, so that its symbols and types are correctly exported
and found by the main program? Or is it a case where the
SelectedFileObj ect in the plugin is, as far as the program can
tell, totally unrelated to the class of the same name in the
main program.

Normally, a well designed plugin will be built and loaded in a
manner such that most of the symbols in it are NOT visible
outside it---the plugin interface may very well use a type
SelectedObject, which must be common to all plugins, but you
typically don't want conflicts just because two different
plugins decide to use the same name for the derived class---you
want it to be two different classes, as if they really had
different names. And of course, if this is the case,
typeid(...).nam e() will return the same value for the two
different classes.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

May 25 '07 #16
On May 25, 8:37 am, mark <trid...@ihug.c o.nzwrote:
>
SOFORef SOCastToSOF(SOR ef sor) {
SelectedFORef sof=nil;
...
return sof;
};
Is SelectedFORef castable to SOFORef ?(you have not declared the later
type.)

May 25 '07 #17
mark wrote:
In article <5b************ **@mid.individu al.net>,
Ian Collins <ia******@hotma il.comwrote:
>mark wrote:
>>SelectedFOR ef sof=nil; <-- habit of setting vars to defaults.
Pointless when it gets assigned on the next line...
>>sof=dynamic_c ast<SelectedFOR ef>(sor); <-- sof is set to nil/NULL by
dynamic_cas t

This routine is invoked by a plugin. sor is passed from APP -PLUGIN
-APP (above routine). The plugin just has a pointer to work with.
What is a plugin? The objects aren't being mangled by another language
by any chance?


They shouldn't as the plugin (loadable bundle/library) only recieves a
pointer.

The plugin uses this definition:
// parent class
typedef void* SelectedObjectR ef;
typedef SelectedObjectR ef SORef; // shorter name

// selected file objects
typedef void* SelectedFileObj ectRef; // subclass of SORef
typedef SelectedFileObj ectRef SOFORef;

The plugins are not necessarily written in C++.
The test plugin is written in C.

Also, some testing shows that if the object passes through the plugin,
the casting fails. Otherwise if the casting routine is called directly
by the owning app, it succeeds. This means there is some mangling going
on somewhere.
Does the same pointer come out as went in, it looks like the vtable may
be getting lost.

--
Ian Collins.
May 25 '07 #18
In article <11************ **********@u30g 2000hsc.googleg roups.com>,
terminator <fa***********@ gmail.comwrote:
On May 25, 8:37 am, mark <trid...@ihug.c o.nzwrote:

SOFORef SOCastToSOF(SOR ef sor) {
SelectedFORef sof=nil;
...
return sof;
};

Is SelectedFORef castable to SOFORef ?(you have not declared the later
type.)
Really bad day for thinking yesterday.

Here's everything:

Mac OS X. XCode 2.4.

Here are the classes:

typedef class SelectedObject* SelectedObjectR ef;
typedef SelectedObjectR ef SORef;
typedef UInt32 SOOwnerID;

class SelectedObject {
UInt16 refCt;

SelObjectClass objectClass;
OSType ready;
protected:
SOOwnerID ID; // need to identify where the SO belongs. An SO in one
view will have
// different select flags to an SO in another view
SelObjectType objectType; // NYI
SelectionFlag selections;

static CFMutableSetRef soCache;
static void SOCacheSetProc( const void* value, void* ctx);
friend SORef CheckSOCache(Se lObjectClass objClass, UInt16 objType,
SOOwnerID iID, void* data);
virtual OSStatus CheckCache(SelO bjectClass objClass, UInt16 dataType,
void* data,
SORef *sor);
// the arrays are used to send one select/deselect event when a whole
lot
// of objects are selected/deselected. Sending 1000+ deselected
events is not a good
// idea
static CritRgn recentSelRgn;
static CFMutableSetRef recentlySelecte d;
static CFMutableSetRef recentlyDeselec ted;
static OSStatus PostMassSelOfOw ner(SOOwnerID ID, Boolean selOrDesel,
CFArrayRef itsItems);
static OSStatus PostMassSelectE vents(SOOwnerID whichID=0); // clears
both arrays after sending
// dtEventKindObje ctsSelected & dtEventKindObje ctsSelected
// If zero is passed, all are sent (in seperate events for each ID)
OSStatus AddToSelected() ;
OSStatus AddToDeselected ();

void SOCleanup();
public:
SelectedObject( SelObjectClass theObjClass, SOOwnerID ID);
SelectedObject( const SelectedObject &obj);
virtual ~SelectedObject ();
UInt16 Retain();
UInt16 Release();
SelObjectClass GetObjectClass( );
virtual SelObjectType GetObjectType() ; // NYI. Will always return
zero.
SOOwnerID GetOwnerID();

virtual CFStringRef CopySOString();

virtual UInt64 GetSOData64(); // these two will always return zero
for the base class
virtual UInt32 GetSOData32(); // it is up to the subclasses to return
the correct values

SelectionFlag GetSelectFlags( );
void DefineSelectFla g(SelectionFlag theFlags, Boolean newValue);
void ToggleSelectFla g(SelectionFlag theFlags);
Boolean IsSelectedOr(Se lectionFlag whichFlags); // returns true if
any of the passed flags are set
Boolean IsSelectedAnd(S electionFlag whichFlags); // returns true if
all of the passed flags are set
Boolean AnySelection(); // returns true is any flag is set

void PostSelectedEve nt(Boolean selected);

virtual Boolean operator==(Sele ctedObject &obj);

virtual void DebugPrint(UInt 32 v=0); // printf
virtual CFStringRef DebugString(UIn t32 v=0); // CFStringRef -CFShow
};

//-----------------------------------------------------------------------
--------------

class SelectedFileObj ect:public SelectedObject {
OSType sfoReady;
protected:
FSRef fsr;

virtual OSStatus CheckCache(SelO bjectClass objClass, UInt16 dataType,
void* data,
SORef *sor);
void SFOCleanup();
public:
SelectedFileObj ect(const FSRef* fsrptr, SOOwnerID ID);
SelectedFileObj ect(const char* cpath, SOOwnerID ID);
SelectedFileObj ect(CFURLRef url, SOOwnerID ID);
SelectedFileObj ect(const SelectedFileObj ect &obj);
~SelectedFileOb ject();

CFStringRef CopySOString();
UInt64 GetSOData64();
UInt32 GetSOData32();
FSRef* GetFSRefPtr();
virtual CFStringRef CopyName();

Boolean operator==(Sele ctedFileObject &obj);

void DebugPrint(UInt 32 v=0); // printf
CFStringRef DebugString(UIn t32 v=0); // CFStringRef -CFShow
};

typedef class SelectedFileObj ect* SelectedFORef;
typedef SelectedFORef SOFORef;

The plugin header uses this typedef:

// parent class
typedef void* SelectedObjectR ef;
typedef SelectedObjectR ef SORef; // shorter name

// selected file objects
typedef void* SelectedFileObj ectRef; // subclass of SORef
typedef SelectedFileObj ectRef SOFORef;

Here is the casting routine: (it is exported using extern "C")

SOFORef SOCastToSOF(SOR ef sor) {
if (sor==nil) {return nil;}
SelectedFORef sof=nil;
printf("%s\n", typeid(*sor).na me()); (1)
printf("%s\n", typeid(Selected FileObject).nam e()); (2)
if (typeid(*sor)== typeid(Selected FileObject)) { (3)
sof=(SOFORef)so r;
}
else {sof=nil;}
// sof=dynamic_cas t<SelectedFORef >(sor);
return sof;
};

The routine is used by plugins.
The plugins receive a SORef from the parent application via another
accessor routine and are
passed in an CFArray.
All the plugins ever receive are pointers.
The passed SORef is not guaranteed to be a SOFORef (much like a CFType
is not guaranteed to be a CFString). So they use this routine to convert
it if possible.

(1) & (2) typeid statements print '18SelectedFile Object' .
(3) always evaluates to false when the routine is called by the plugin.
But, if the owning app calls this casting routine directly, it succeeds.
Someone from a C++ newsgroup suggested that the vtable is getting 'lost'
or mangled when passed through the plugin.

Last bit of code. The CFArray callbacks:

const void* SORefRetain(CFA llocatorRef alloc, const void* value) {
SORef sor=(SORef)valu e;
sor->Retain();
return value;
};

void SORefRelease(CF AllocatorRef alloc, const void* value) {
SORef sor=(SORef)valu e;
sor->Release();
};
May 26 '07 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
3585
by: Aaron W. West | last post by:
Fun with CAST! (Optimized SQLServerCentral script posts) I found some interesting "tricks" to convert binary to hexadecimal and back, which allow doing 4 or 8 at a time. Test code first: -- These two have the same output, other than the width: select dbo.ufn_vbintohexstr(0x123456789abcdef1234) select 0x123456789abcdef1234
15
1730
by: Gregg Woodcock | last post by:
My compiler (m68k-gcc) does not allow this (simplified example; not my real code) and I don't see why not: { char *arrayCharPtr1 = {"a", "ab", NULL}; char *arrayCharPtr2 = {"A", "AB", NULL}; char *arrayCharPtrVar = ((someBoolean) ? arrayCharPtr1 : arrayCharPtr2); // <-error here! StrCopy(someString, arrayCharPtr); }
6
1335
by: Adam Warner | last post by:
Hi all, When adding variable length arrays to my program I created the elements as type struct o *. This is because /most/ of the time the VLAs contains pointers to struct o objects (these objects are as stringently aligned as any C type in the implementation). Occasionally a single element is actually a pointer to another VLA of pointers to struct o objects (and occasionally I'm storing an integer index (of type ptrdiff_t) as an...
17
2672
by: Hazz | last post by:
In this sample code of ownerdraw drawmode, why does the '(ComboBox) sender' line of code need to be there in this event handler? Isn't cboFont passed via the managed heap, not the stack, into this cboFont_DrawItem event handler? Why does it need to be cast? -hazz ,................. cboFont.Items.AddRange(FontFamily.Families); } private void cboFont_DrawItem(object sender,
1
5493
by: Alpha | last post by:
I have a Window based application that shows up still running in the task manager when I close it. It reaches the "this.close" statement and then it stops at the "}" at the section of the following code after the "Application.Run(new VMSMain());": static void Main() { Application.Run(new VMSMain()); }
5
3424
by: Nick Flandry | last post by:
I'm running into an Invalid Cast Exception on an ASP.NET application that runs fine in my development environment (Win2K server running IIS 5) and a test environment (also Win2K server running IIS 5), but fails on IIS 6 running on a Win2003 server. The web uses Pages derived from a custom class I wrote (which itself derives from Page) to provide some common functionality. The Page_Load handler the failing webpage starts out like this: ...
5
2362
by: Frederick Gotham | last post by:
Before I begin, here's a list of assumptions for this particular example: (1) unsigned int has no padding bits, and therefore no invalid bit- patterns or trap representations. (2) All types have the same alignment requirements. (3) sizeof(double) >= sizeof(unsigned) ===================================== We can cast from double to unsigned int as follows:
9
3423
by: Ivan Jericevich | last post by:
In my code below at the line 'response' a blip sound is heard and the program exits the sub -- No MsgBox is displayed. What am I doing wrong? If nonNumberEntered = True Then msg = "Enter numbers only" style = MsgBoxStyle.OkOnly title = "ERROR in cast"
1
1825
by: DerekBaker | last post by:
I had this code previously: void App::FillFontBox(HWND PrefsBox) { EnumFontFamilies(hdc,(LPCTSTR)NULL,(FONTENUMPROC)EnumFontNamesProc,(long)this);
0
8674
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8603
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
8895
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8861
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6518
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5860
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4369
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4619
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
2001
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.